手动加载的程序集中的新实例

时间:2014-11-12 19:46:29

标签: c#

对于自动更新方案,我希望app能够自动从云中下载更新的dll。在我的VS项目中,我引用了一个程序集(v1.0.0.0)。我想在运行时加载它的更新版本(例如v1.1.0.0),以便在我新建它时:

var class1 = new Class1();

我希望从程序集版本v1.1.0.0中获取类型(Class1)的实例。这甚至可能吗?

注意:我没有想过用反射创建实例类型Class1的方法,但是要新建它。

1 个答案:

答案 0 :(得分:2)

您需要使用assembly redirection告诉加载程序在绑定程序集时为您的应用程序加载更新(但仍然兼容)的程序集。这是您在app.configweb.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