c# - 通过配置加载依赖程序集
问题描述
我有一个视觉工作室项目,它运行得非常好。但是对于将不同的 dll 放置在不同的文件夹中的部署,出现了新的客户端要求。
我们有一个框架 dll,可以在不同的项目中使用。此框架 dll 依赖于一些第三方 dll。因此,当我从我的项目中使用这个 dll 时,每个依赖的 dll 都会在构建时复制到我的本地,因为 CopyLocal 属性为 true。
但是现在有了新的要求,我们不能将 CopyLocal 属性设置为 True。客户端不需要任何 dll 的本地副本,而是希望在某个位置与框架相关的 dll。当我这样做时,相关的 DLL 不会被加载。
我知道我有两个选择:
- 我可以将它们放入 GAC,但我不想这样做,因为我希望它们支持 xcopy。
- 使用反射(但我不确定这是正确的方法)
我们可以使用配置做任何事情吗?
解决方案
您可以使用<probing> 配置元素配置程序集探测路径:
指定公共语言运行时在加载程序集时要搜索的应用程序基子目录。
来自 MSDN 的示例:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
但是,如果有问题的程序集位于应用程序库之外(“这是执行应用程序的根位置”),则您拥有<codeBase> 配置元素:
指定公共语言运行时可以在哪里找到程序集。
来自 MSDN 的示例:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="myAssembly"
publicKeyToken="32ab4ba45e0a69a1"
culture="neutral" />
<codeBase version="2.0.0.0"
href="http://www.litwareinc.com/myAssembly.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
有关运行时如何定位程序集的详细信息,您可以参考这篇 MSDN 文章。
正如 OP 所指出的,不幸的是, codeBase元素只是强命名程序集的可用选项。对于私有程序集,您需要一种解决方法。在此讨论中可以找到一些可行的想法,例如:
- 文件系统链接(NTFS 连接点)+探测元素或AppDomainSetup.PrivateBinPath
- AppDomain.CurrentDomain.AssemblyResolve事件
我已经测试了后者并且可以确认它有效:
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
Assembly.LoadFile(Path.Combine(Settings.Default.AssemblyPath, Path.ChangeExtension(e.Name.Substring(0, e.Name.IndexOf(',')), ".dll")));
推荐阅读
- sql-server - 提供的时间值的小数部分溢出异常 SQL Server 2017
- java - 获取elasticsearch中搜索值匹配的字段名称
- drop-down-menu - 手风琴内的 Bootstrap 4 下拉菜单
- solr - Solr如何在搜索结果中区分大小写字符
- css - 隐式网格有什么我不能用显式网格做的吗?
- reactjs - 发送函数 throw `spread operator` 不起作用,但添加了状态值
- sql - 以函数为值执行 \set 命令
- c++ - How to produce compiler error if default template is used?
- python - Python 3.7 上的触发器(Networktest)安装
- javascript - 如何在javascript中将blob下载为mp4?