3

我们有一个我们分发的 DLL,它对其他 DLL 具有外部依赖性。我们没有冒险丢失 DLL 或存在潜在的混合匹配情况,而是将 DLL 嵌入到我们自己的 DLL/EXE 中并在运行时加载它以满足运行时链接。

问题:

A) 之间

  • 将 DLL 嵌入到我们的 .EXE/.DLL 中,然后在运行时将其加载到内存中,然后
  • 将 DLL 作为一个单独的文件保存在文件系统上,然后让系统为我们加载它

哪种方法消耗更多内存,大约消耗多少?

B)有没有人有比上述更好的方法?特别是对于下面详细信息中的第 3 项。


有兴趣的我们的流程的详细信息:

  1. 在我们知道在调用程序集中的代码之前运行的部分注册 AssemblyResolve 事件(例如:初始化时间)

    public void SomeInitCode()
    {
        ...
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            string[] assemblyDetail = args.Name.Split(',');
            var assemblyName= assemblyDetail[0] + ".dll";
    
            var thisAssembly = Assembly.GetExecutingAssembly();
            var allResourceNames = thisAssembly.GetManifestResourceNames();
    
            string requiredResName = allResourceNames.SingleOrDefault(a => a.EndsWith(assemblyName));
    
            using (var input = thisAssembly.GetManifestResourceStream(requiredResName))
            {
                return input != null
                     ? Assembly.Load(StreamToBytes(input))
                     : null;
            }
        };
        ...
    }
    
    static byte[] StreamToBytes(Stream input)
    {
        var capacity = input.CanSeek ? (int)input.Length : 0;
        using (var output = new MemoryStream(capacity))
        {
            int readLength;
            var buffer = new byte[4096];
    
            do
            {
                readLength = input.Read(buffer, 0, buffer.Length);
                output.Write(buffer, 0, readLength);
            }
            while (readLength != 0);
    
            return output.ToArray();
        }
    }
    
  2. 嵌入程序集。这是通过“添加现有项目”到 .NET 项目 => 选择 .dll => 好的来完成的。返回并选择 .dll 并在属性中将“构建操作”更改为“嵌入式资源”。

  3. 我们仍然需要添加相同的 .DLL 作为引用,并且仍然需要在using ExternalNamespace;使用它的类顶部的语句。如果没有,构建过程将失败,因为它在编译时看不到外部 DLL 代码。因此,作为构建后操作,我们必须从最终bin文件夹中删除 .DLL 文件(不是嵌入式克隆)。

4

2 回答 2

2

正如马克所建议的那样。

我只会使用 ILMerge 将所有东西放在一起。

然而,这可能是不可能的,但应该适用于“纯”托管程序集(包括使用 的程序集unsafe)。

于 2013-04-10T11:13:54.827 回答
1

答:只要内部组件本身没有太大的尺寸(例如,一些巨大的嵌入式资源),它应该可以接受- 这是一个有点扭曲的答案,但我没有比这更好的答案了“测量它”。我偶尔会做非常相似的事情(并且出于类似的原因)。

f4B:将参考属性 ( )上的“复制本地”设置为Falseusing ExternalNamespace;即使文件在同一个项目中,您也需要- 这只是让命名空间发挥作用。

于 2013-04-10T11:04:35.890 回答