在c#中封装子命名空间

时间:2012-04-11 10:47:37

标签: c# namespaces encapsulation

我有一个类库项目。在这个项目中,我有一些文件夹来分离逻辑。

假设我有一个 DAL 库,在DAL中我有 IDAL DALFactory SQLServerDAL 。<登记/> 现在,当我将DAL dll提供给其他程序员时,他可以使用所有子系统。假设我不希望他使用SQLServerDal而是其他人。我如何封装SQLServerDAL,以便没有人能够意识到它存在。

感谢。
修改
更有意义:

using DAL; // it can be written
using DAL.IDAL; // it can be written
using DAL.DALFactory; // it can be written
using DAL.SQLServerDAL; // it dont want to allow anyone write that

4 个答案:

答案 0 :(得分:1)

这与命名空间无关,因为它们在元数据级别上不存在。根据其他人的建议,将命名空间SQLServerDAL中的所有类都设置为内部,或者使SQLServerDAL成为静态内部类而不是命名空间。在这种方法中,SQLServerDAL中的类将成为嵌套类,并且将无法从DAL程序集外部访问:

// what you have now:
namespace DAL.SQLServerDal
{
    public class A {}
    public class B {}
}

// in other assembly
using DAL.SQLServerDal ; // ok
new A () ; // ok

// with internal classes:
namespace DAL.SQLServerDal
{
    internal class A {}
    internal class B {}
}

// in other assembly
using DAL.SQLServerDal ; // ok
new A () ;               // error: A is inaccessible due to protection level

// what I propose:
namespace DAL
{
    internal static class SQLServerDal
    {
        public class A {}
        public class B {}
    }
}

// in other assembly
using DAL.SQLServerDal ; // error: namespace DAL.SQLServerDal does not exist

但是,如果使用反射或代码生成,如果您使用的库不能正确支持嵌套类,则可能会出现问题。

答案 1 :(得分:0)

不确定这是否是最佳解决方案,但是: -

将SQLServerDAL类更改为internal。然后在properties / assemblyinfo.cs文件中添加任何需要访问SQLServerDAL的DLL:

using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Fully.Qualified.AssemblyName")]

这显然无法防止出现异议,但任何消费你的dll都不会公开显示。

答案 2 :(得分:0)

您说的这些“子DLL”是什么?

  

我有一个类库项目。

由此我假设你有一个DLL。在这种情况下,没有“子DLL”这样的东西。在项目的子文件夹中定义的类是该单个DLL的一部分。他们在子文件夹中的事实没有任何区别。如果已将子文件夹名称添加到每个类的命名空间中,则所有这些意味着结果类型的名称将包含其中的文件夹名称。

如果您想在内部使某些类型,请使用internal关键字。遗憾的是,无法在给定的子文件夹内部创建所有类。如果您想这样做,则需要将internal关键字添加到子文件夹中的每个类定义中。

答案 3 :(得分:0)

如评论中所述,您可以将要隐藏的DLL添加为父项目中的资源文件。因此,您必须添加已编译的DLL并在解决方案中将其标记为“嵌入式资源”。

第二步是在父图书馆中加载DLL以便访问它。

Stream stream = GetType().Assembly
               .GetManifestResourceStream("<<FULL QUALIFIED DLL NAME>>");
if (stream == null)
    throw new InvalidDataException("<<FULL QUALIFIED DLL NAME>> not found.");

byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int) stream.Length);

Assembly assembly = Assembly.Load(buffer);

获得程序集引用后,您可以继续获取要访问的类和方法。

var sqlServerDAL = assembly.GetType("<<FULL QUALIFIED CLASS NAME>>");
var method = sqlServerDAL.GetMethod("<<METHOUD>>", BindingFlags.Public);

我知道这是一种混淆某些类的非常讨厌的方法,但它是有效的。因为DLL不在目录中,所以也不能简单地键入命名空间来访问类。