对于自动更新方案,我希望app能够自动从云中下载更新的dll。在我的VS项目中,我引用了一个程序集(v1.0.0.0)。我想在运行时加载它的更新版本(例如v1.1.0.0),以便在我新建它时:
var class1 = new Class1();
我希望从程序集版本v1.1.0.0中获取类型(Class1)的实例。这甚至可能吗?
注意:我没有想过用反射创建实例类型Class1的方法,但是要新建它。
答案 0 :(得分:2)
您需要使用assembly redirection告诉加载程序在绑定程序集时为您的应用程序加载更新(但仍然兼容)的程序集。这是您在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