2014-09-10 35 views
1

目前,我正在开发一个.NET爱好项目,该项目涉及与彼此组合的对象的复杂系统。但是,我遇到了一个小问题,我无法在.NET中找到支持在运行时替换代码的机制,并且能够处理先前加载的旧代码。这意味着动态地替换模块/对象,并且几乎立即向用户显示更改,例如,当他重新启动一个过程时,而不是整个程序。.NET中的模块化系统可以在运行时进行更改

我已经考虑过为每个会话单独设置AppDomain并将必要的程序集加载到其中的可能性,但这看起来有点太昂贵。我还应该提到,每个会话都从一个常见的程序集基础中受益,例如,连接到数据库,这意味着将这些类加载到每个会话中。来自单独的AppDomain来回编组数据还表示额外开销(可以在数据通过网络发送到客户端应用程序时使用,代码为管理会话的主要AppDomain中包含的代码)。

是否有一个框架或方法来取代/卸载特定部分的代码?它如何在现实世界的应用程序中完成?有没有解决方法?或者我选择了一套错误的工具?

回答

3

您需要某种具有良好定义的接口的插件系统。然后在运行时二进制文件(您的插件* .dll)中加载并从中创建对象,然后在其上执行方法。 当您创建一个系统时,您的插件中的对象必须通过您的IPluginManager创建,您在运行时替换代码没有问题。:)

或者

你有这样的事情有哪些,将根据需要编译(在内存中)*的.cs文件的文件夹,并创建你想从他们使用,并呼吁他们的方法的对象。 这与上面的基本相同,没有在运行时编译。

从那里你可以做出进一步的改进。

编辑: 像你写的唯一的问题,而不使用AppDomain是一旦加载的程序集不能被卸载。但这不是一个真正的问题。

0

你可以看看MEF。它代表:托管扩展框架
这是另一篇关于它的文章MEF on codeproject

它用于在运行时编写它们来加载dll。这是通常用于plugins或其他任何你放入文件夹并期望它运行的东西。

下面是一些教程的链接,以及:Where can I learn about MEF?

+0

我认为'MEF'是一个选项,但我必须再次自己做'AppDomain'管理。 – ax1mx2 2014-09-10 14:18:00

1

我不认为你需要单独的AppDomain:您可以动态地在当前的AppDomain中加载程序集。并且每个程序集可能应该实现一些定义的接口(取决于您的使用情况)。例如,您可以使用FileSystemWatcher类来根据需要加载/卸载程序集。

http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx

+2

尽管如此,您无法从AppDomain卸载程序集;这就是为什么需要单独的AppDomain,如果你想卸载任何东西(在这一点你卸载整个AppDomain)。 – 2014-09-10 12:08:08

+0

你说得对。有必要卸载整个AppDomain以“卸载”一个程序集。 – DvS 2014-09-10 13:49:39

0

是的,你说得对,这是不可能简单地卸载的组件(只应用程序域)。但我认为ASP.Net vNext的其中一项功能是只具有内存中程序集的功能,并且只需更改驱动器上的源代码即可自动编译和加载。因此,必须存在一个机制来卸载以前的版本。

我认为他们是通过简单地创建一个AppDomain来重新加载所有程序集以避免任何跨域通信。但是我不知道,也许如果你想深入了解他们如何在ASP.NET中做这些事情的机制,你可能会找到一个好的解决方案。有关vNext热门话题的更多信息,您也可以在Scotts Blog找到。

0

嗯,我发现了2个适用于我的解决方案,我想分享一下。第一个是使用CollectibleAssembly并定义类型。这当然有点棘手,并且对这种类型的动态装配施加了许多限制。 另一种选择是使用脚本语言,如IronPythonIronRuby。新的Roslyn编译器的一个很棒的功能还在于它还提供了脚本API,而以前在.NET框架中没有。更重要的是,Roslyn脚本语言看起来非常像它们的成熟等价物(C#或VB)。我还发现了它的一个小小的example