目前我正在开发一个.NET爱好项目,该项目涉及一个复杂的对象系统,它们可以相互结合使用。但是,我遇到了一个小问题,我无法在.NET中找到一种机制来支持在运行时替换代码,并且能够处理以前加载的旧代码。这意味着动态替换模块/对象并几乎立即显示对用户的更改,例如,当他重新启动程序时,而不是整个程序。
我已经考虑过为每个会话分别AppDomain
并将必要的程序集加载到其中的可能性,但这似乎有点过于昂贵。我还应该提到,每个会话都受益于程序集的通用基础,例如,连接到数据库,因此这意味着将这些类加载到每个会话中。从单独的AppDomain
来回分拣数据也代表了额外的开销(可以在数据通过网络发送到客户端应用程序时使用,代码包含在主AppDomain
中,用于管理会话)。
是否有替换/卸载特定代码部分的框架或方法?它是如何在现实世界的应用程序中完成的?可以有一个解决方法吗?或者我选错了一套工具?
答案 0 :(得分:3)
您需要某种具有良好定义的接口的插件系统。然后加载运行时二进制文件(您的插件* .dll)并从中创建对象,然后在其上执行方法。 当您创建一个系统,其中必须通过IPluginManager创建插件中的对象时,在运行时替换代码没有问题。 :)
或者
你有类似* .cs文件的文件夹,它将按需编译(在内存中)并创建你想要使用它们的对象并调用它们上的方法。 这与上面的基本相同,没有在运行时进行编译。
从那里你可以进一步改进。
编辑: 就像你写的那样,不使用AppDomain的唯一问题是一旦加载的程序集无法卸载。但这不是一个真正的问题。
答案 1 :(得分:1)
我认为您不需要单独的AppDomains:您可以在当前AppDomain中动态加载程序集。每个程序集应该实现一些定义的接口(取决于您的用法)。例如,您可以使用FileSystemWatcher类根据需要加载/卸载程序集。
请参阅http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
答案 2 :(得分:0)
您可以查看MEF。它代表:托管扩展性框架 这是另一篇关于它的文章MEF on codeproject。
它用于通过编写它们来在运行时加载dll
。这通常用于plugins
或您放入文件夹并期望它运行的任何其他内容。
此处还提供了一些指向其他教程的链接:Where can I learn about MEF?
答案 3 :(得分:0)
是的,你是对的,不可能只是卸载一个程序集(只有AppDomains)。但我认为ASP.Net vNext的一个特性是能够只拥有内存中的程序集,当你只是改变驱动器上的源代码时,它会自动编译和加载。因此,卸载以前的版本必须存在一种机制。
我认为他们只是通过创建一个AppDomain来实现这一点,其中所有程序集再次加载以避免任何跨域通信。但我真的不知道,也许如果你想深入了解他们如何在ASP.NET中做这些东西的机制,你可能会找到一个很好的解决方案。有关vNext热门话题的更多信息,您也可以在Scotts Blog找到。
答案 4 :(得分:0)
好吧,我找到了两个对我有用的解决方案,我想分享一下。第一个是使用CollectibleAssembly
并定义类型。这当然有点棘手,并且对这种类型的动态组合施加了许多限制。
另一种选择是使用脚本语言,如IronPython
或IronRuby
。新的Roslyn编译器的一个很棒的特性是它还提供了以前在.NET框架中不可用的脚本API。更重要的是,Roslyn脚本语言往往看起来非常像他们的完整等价物(C#或VB)。而且我还发现了一小部分example的能力。