简体   繁体   中英

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). 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.

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. 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. I also found a hack. using Bll = MyApp.Bll which will enforce the Bll.ApiService to be used. 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!

  2. Require fully qualified names. 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 .

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 Dal = MyApp.Dal and using 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). UI should reference BLL, that should reference DAL
  2. If they have different namespaces, you must either declare a using Namespace; statement or use a full qualified name, such as Namespace.Class
  3. In order to be used at a using(obj){...} block, obj must implement the IDisposable interface. 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 . You have a namespace called 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 .

If all you're after is the ability to refer to the MyApp.Bll namespace with the symbol Bll , you can alias the namespace:

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.

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

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:

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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