我们有一个我们分发的 DLL,它对其他 DLL 具有外部依赖性。我们没有冒险丢失 DLL 或存在潜在的混合匹配情况,而是将 DLL 嵌入到我们自己的 DLL/EXE 中并在运行时加载它以满足运行时链接。
问题:
A) 之间
- 将 DLL 嵌入到我们的 .EXE/.DLL 中,然后在运行时将其加载到内存中,然后
- 将 DLL 作为一个单独的文件保存在文件系统上,然后让系统为我们加载它
哪种方法消耗更多内存,大约消耗多少?
B)有没有人有比上述更好的方法?特别是对于下面详细信息中的第 3 项。
有兴趣的我们的流程的详细信息:
在我们知道在调用程序集中的代码之前运行的部分注册 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(); } }
嵌入程序集。这是通过“添加现有项目”到 .NET 项目 => 选择 .dll => 好的来完成的。返回并选择 .dll 并在属性中将“构建操作”更改为“嵌入式资源”。
我们仍然需要添加相同的 .DLL 作为引用,并且仍然需要在
using ExternalNamespace;
使用它的类顶部的语句。如果没有,构建过程将失败,因为它在编译时看不到外部 DLL 代码。因此,作为构建后操作,我们必须从最终bin
文件夹中删除 .DLL 文件(不是嵌入式克隆)。