简体   繁体   English

C#的命名空间范围问题

[英]namespace scoping issues with C#

So i have a program that is a 3 tiers program, the UI, the BLL (Business Logic Layer) and of course the DAL (Data Access Layer). 所以我有一个3层程序,即UI,BLL(业务逻辑层)和DAL(数据访问层)。 The UI always speaks to the BLL of which uses the DAL to retrieve data units, assembling them in a format and returning them to the UI. UI总是与BLL对话,后者使用DAL检索数据单元,将它们组合成一种格式并将其返回给UI。

Since this is for my job i want to make sure that conventions are ALWAYS used (not a big fan of everyone programming their own style wherever they want!). 由于这是我的工作,因此我想确保始终使用约定(不是每个人都可以在自己想要的地方编程自己的样式的忠实粉丝!)。 So i thought it would be nice to have something like this. 所以我认为拥有这样的东西会很好。

using (Bll.MyService service = new Bll.MyService()) {
    //My Sweet Code
} 

BUT!!! 但!!! If the Bll is located in a namespace that my UI is not, this will not be an option. 如果Bll位于我的UI不在的命名空间中,那么这将不是一个选择。 Here is a more lenghty example of what i mean. 这是我的意思的一个比较宽松的例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyApp;

//Entry point
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //I want to be able to do a using MyApp and access the Bll objects!
            Bll.ApiService service = new Bll.ApiService(); //ERROR LINE
        }
    }
}

//Data access layer
namespace MyApp.DAL
{
    class ApiDataAccessor
    {
        public int MyVar = 1;
    }
}

//The bacon letuce layer of course
namespace MyApp.Bll
{
    class ApiService
    {
        public void MyFunction()
        {
            //todo: make more awesome
        }
    }
}

If anyone has any suggestions that would be great! 如果有人有任何建议,那就太好了! Thanks! 谢谢!

EDIT: 编辑:

Added the //ERROR LINE to a comment in the code so to make the error obvious. 在代码中的注释中添加了//ERROR LINE ,以使错误显而易见。 I also found a hack. 我还发现了一个黑客。 using Bll = MyApp.Bll which will enforce the Bll.ApiService to be used. using Bll = MyApp.Bll ,它将强制使用Bll.ApiService I do not know if i like this solution (as it easy to mess up and be angry until i realize that i did not alias the namespace). 我不知道我是否喜欢这种解决方案(因为很容易弄乱和生气,直到我意识到我没有为命名空间起别名)。

EDIT (Again): 编辑(再次):

There are a few solutions. 有一些解决方案。

  1. using Bll = MyApp.Bll at the top and then all objects in that namespace have to be referenced with Bll.MyObject which is what we wanted! 在顶部using Bll = MyApp.Bll ,然后必须使用Bll.MyObject引用该命名空间中的所有对象!

  2. Require fully qualified names. 需要完全限定的名称。 MyApp.Bll.MyObject . MyApp.Bll.MyObject Which is what we did not want (as it can get verbose with large namespaces) 这是我们不想要的(因为它在大型名称空间中可能变得冗长)

  3. Just include the namespace up top. 只需在顶部包含名称空间即可。 using MyApp.Bll . using MyApp.Bll

In summary, we were hoping to get using MyApp in some way to allow us to reference all those namespaces and their objects like Bll.ThisObject and Dal.ThatObject but instead, if that were a solution desired, the only way to accomplish that would be to include 2 using statements, which are aliased. 总而言之,我们希望以某种方式using MyApp ,以允许我们引用所有这些名称空间及其对象,例如Bll.ThisObjectDal.ThatObject但相反,如果Dal.ThatObject ,则唯一的方法是包括2个using语句,它们是别名。 using Dal = MyApp.Dal and using Bll = MyApp.Bll using Dal = MyApp.Dalusing Bll = MyApp.Bll

Thanks everyone for your help. 感谢大家的帮助。

Here is the solution 这是解决方案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyApp;
using Bll = MyApp.Bll;

//Entry point
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //I want to be able to do a using MyApp and access the Bll objects!
            Bll.ApiService service = new Bll.ApiService(); // <-- it works.
        }
    }
}

//Data access layer
namespace MyApp.DAL
{
    class ApiDataAccessor
    {
        public int MyVar = 1;
    }
}

//The bacon letuce layer of course
namespace MyApp.Bll
{
    class ApiService
    {
        public void MyFunction()
        {
            //todo: make more awesome
        }
    }
}

Ok, let's see: 好吧,让我们来看看:

  1. If those layers are implemented on different assemblies ( Class Library projects), then you must be sure to reference them (right click the project > Add Reference > Projects). 如果这些层是在不同的程序集( Class Library项目)上实现的,则必须确保引用它们(右键单击项目>添加引用>项目)。 UI should reference BLL, that should reference DAL UI应该引用BLL,而应该引用DAL
  2. If they have different namespaces, you must either declare a using Namespace; 如果它们具有不同的命名空间,则必须声明一个using Namespace; statement or use a full qualified name, such as Namespace.Class 语句或使用完全限定名称,例如Namespace.Class
  3. In order to be used at a using(obj){...} block, obj must implement the IDisposable interface. 为了在using(obj){...}块上使用, obj必须实现IDisposable接口。 This is a by design requirement of the language 这是语言的设计要求

Note that I'm note saying that this is the best approach, neither that you should change anything at your project. 请注意,我注意到这是最好的方法,也不要在项目中进行任何更改。 If you have a broader question, such as "is this the best solution", then we may be able to discuss it. 如果您有更广泛的问题,例如“这是最好的解决方案”,那么我们也许可以讨论它。

I think the confusion lies here: you don't have a namespace called Bll . 我觉得困惑就在这里:你没有一个叫做命名空间Bll You have a namespace called MyApp.Bll . 您有一个名为MyApp.Bll的命名空间。

Regardless of having a using MyApp directive, you need to either add a using MyApp.Bll directive and then just reference ApiService directly in your code, or fully-qualify the class as MyApp.Bll.ApiService . 不管using MyApp指令如何,都需要添加using MyApp.Bll指令,然后直接在代码中引用ApiService ,或者完全将类限定为MyApp.Bll.ApiService

If all you're after is the ability to refer to the MyApp.Bll namespace with the symbol Bll , you can alias the namespace: 如果所有你后是指的能力MyApp.Bll用符号命名空间Bll ,你可以别名命名空间:

using Bll = MyApp.Bll

Also, based on comments on the question and various answers, it's worth pointing out that the using statement , which provides a convenient way to declare and clean up unmanaged resources, and appears as a block in your code is not the same as the using directive that imports namespaces. 另外,基于对问题的注释和各种答案,值得指出的是using语句 ,它提供了一种方便的方法来声明和清除非托管资源,并且在代码中显示为块,与using指令不同导入名称空间。

您可以使用其名称空间完全限定类型名称:

MyApp.Bll.ApiService service = new MyApp.Bll.ApiService();

Personally, I prefer using statements that are more specific. 就个人而言,我更喜欢使用更具体的陈述。 You will likely wind up having these in separate class libraries, as Andre has mentioned, and then include those to your project as needed, but in any case I usually use statements such as: 正如Andre所提到的,您可能会把它们放在单独的类库中,然后根据需要将它们包含到您的项目中,但是无论如何,我通常使用如下语句:

using MyApp.Bll;
using MyApp.DAL;

If you are including multiple namespaces where a class reference is ambiguous (ie ApiService is defined in multiple namespaces you are using) then you would identify the class explicitly. 如果您包含多个类引用不明确的名称空间(即ApiService在您使用的多个名称空间中定义),则可以明确标识该类。

MyApp.Bll.ApiService service = new MyApp.Bll.ApiService();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM