手动加载的程序集中的新实例
本文关键字:实例 新实例 程序集 加载 程序 集中 | 更新日期: 2023-09-27 18:30:07
对于自动更新场景,我希望应用程序自动从云中删除更新的dll。在我的VS项目中,我引用了一个程序集(v1.0.0.0)。我想在运行时加载它的新版本(例如v1.0.0),这样当我新建它时:
var class1 = new Class1();
我想从程序集v1.0.0版本中获得一个类型为(Class1)的实例。这可能吗?
注意:我不是在寻找一种方法来制作一个带有反射的实例类型Class1,而是对其进行更新。
在绑定程序集时,您需要使用程序集重定向来告诉加载程序为您的应用程序加载一个更新的(但仍然兼容的)程序集。这是在app.config
或web.config
中执行的操作,具体取决于应用程序类型。例如(取自上面的链接):
<dependentAssembly>
<assemblyIdentity name="someAssembly" publicKeyToken="32ab4ba45e0a69a1"
culture="en-us" />
<bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
oldVersion
允许一个版本范围,因此多个旧版本可以映射到程序集的单个新版本。此外,可能存在多个bindingRedirect
条目。
编辑:
如果要从程序集中动态加载类型,则不能引用该类型本身(也就是说,不能有类似Class1 obj = ...;
的内容(var obj = ...
相同),因为这会将该类型与编译器看到的类型联系起来。程序集重定向可以工作,但如果你不知道正确的版本,你就不能使用它
另一种选择是在主应用程序中定义接口,然后让各种程序集中的各种类型实现这些接口。通过这种方式,您可以动态加载类型并将其强制转换为已知的接口类型。为此,您可以使用依赖项注入(如LightInject等),也可以使用一个配置文件来列出哪些程序集包含接口的特定实现。最后你会做一些类似的事情:
IInterface obj = (IInterface) Activator.CreateInstance ( "assemblyname",
"typename" ).Unwrap ();
这假设assemblyname
引用了一个可以加载的已知程序集,并且typename
在该程序集中,并且它实现了IInterface
。
使用接口可以确保编译时唯一的硬编码类型是接口,并且您可以从任何程序集中加载任何实现,只要这些实现实现了正确的接口。这使得交换各种组件变得容易。
使用DI库,大部分工作都是为您完成的——各种库处理发现在程序集中实现接口的类型,然后在您请求时为您提供一个新实例。
您也可以查看类似问题的答案以获取一些额外信息:https://stackoverflow.com/a/26809961/682404