3

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

假设我有一个DAL库,并且在 DAL 中我有IDALDALFactorySQLServerDAL
现在,当我将 DAL dll 提供给其他程序员时,他可以使用所有的 subDll。假设我不希望他使用 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

4 回答 4

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

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

于 2012-04-12T06:20:53.670 回答
0

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

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

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

这显然不能防止拆卸,但任何使用您的 dll 的人都不会公开看到它。

于 2012-04-11T10:52:41.207 回答
0

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

我有一个类库项目。

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

如果要使某些类型成为内部类型,请使用internal关键字。不幸的是,没有办法将给定子文件夹下的所有类都设为内部。如果您想这样做,您需要将internal关键字添加到子文件夹中的每个类定义中。

于 2012-04-11T12:18:21.010 回答
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不在目录中,也不能简单地键入命名空间来访问类。

于 2012-04-12T06:11:13.500 回答