Currently I'm working on a .NET hobby project that involves a complex system of objects which work in combination with eachother. However, I encountered a little problem, I am unable to find a mechanism in .NET to support replacing code at runtime, and be able to dispose of the old code, loaded previously. This means replacing a module/object dynamically and almost instantly displaying the changes to the user, for example, when he restarts a procedure, but not the whole program.
目前我正在开发一个.NET爱好项目,该项目涉及一个复杂的对象系统,它们可以相互结合使用。但是,我遇到了一个小问题,我无法在.NET中找到一种机制来支持在运行时替换代码,并且能够处理以前加载的旧代码。这意味着动态替换模块/对象并几乎立即显示对用户的更改,例如,当他重新启动过程时,而不是整个程序。
I have already taken into account the possibility of having separate AppDomain
for each session and loading the necessary assemblies into it but this seems a little bit too expensive. I should also mention that every session benefits from a common base of assemblies, for instance, to connect to a database, so this means loading those classes into every single session. Marshalling data back and forth from the separate AppDomain
also represents an additional overhead (could be used when data is sent to the client application through the network, code for this contained in the main AppDomain
, which manages the sessions).
我已经考虑过为每个会话分配AppDomain并将必要的程序集加载到其中的可能性,但这似乎有点过于昂贵。我还应该提到,每个会话都受益于程序集的通用基础,例如,连接到数据库,因此这意味着将这些类加载到每个会话中。从单独的AppDomain来回分拣数据也表示额外的开销(可以在数据通过网络发送到客户端应用程序时使用,代码包含在管理会话的主AppDomain中)。
Is there a framework or way of replacing/unloading particular parts of code? How is it done in real-world applications? Can there be a workaround? Or have I picked the wrong set of tools?
是否有替换/卸载特定代码部分的框架或方法?它是如何在现实世界的应用程序中完成的?可以有一个解决方法吗?或者我选错了一套工具?
5 个解决方案
#1
3
You need some kind of plugin system with well defined interfaces. Then you load at runtime binaries (your plugin *.dll) and create objects from it and then execute methods on it. When you create a system where objects from your plugins must be created through your IPluginManager you have no problem with replacing code at runtime. :)
您需要某种具有良好定义的接口的插件系统。然后加载运行时二进制文件(您的插件* .dll)并从中创建对象,然后在其上执行方法。当您创建一个系统,其中必须通过IPluginManager创建插件中的对象时,在运行时替换代码没有问题。 :)
Or
要么
You have something like a folder with *.cs files which will on demand compiled (in memory) and create the objects you want to use from them and call the methods on them. Which is basically the same like above, without compiling at run time.
你有一个像* .cs文件的文件夹,它将按需编译(在内存中)并创建你想要使用它们的对象并调用它们上的方法。这与上面的基本相同,没有在运行时编译。
From there you can make further improvements.
从那里你可以进一步改进。
EDIT: Like you wrote the only problem without using AppDomain is that once loaded assemblies can't be unloaded. But that's not really a problem.
编辑:就像你写的一样,不使用AppDomain的唯一问题是一旦加载的程序集无法卸载。但这不是一个真正的问题。
#2
1
I don't think you need separate AppDomains: you can dynamically load assemblies within the current AppDomain. And each assembly should probably implement some defined interfaces (depending on your usage). You could use the FileSystemWatcher class, for example, to load/unload assemblies as needed.
我认为您不需要单独的AppDomains:您可以在当前AppDomain中动态加载程序集。每个程序集应该实现一些定义的接口(取决于您的用法)。例如,您可以使用FileSystemWatcher类根据需要加载/卸载程序集。
See http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
请参阅http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
#3
0
You can have a look at MEF. It stands for: Managed Extensibility Framework .
Here's another article about it MEF on codeproject.
你可以看看MEF。它代表:托管可扩展性框架。这是另一篇关于它在codeproject上的MEF的文章。
It is used to load dll
's in runtime by composing them. This is what is usually used for plugins
or anything else you kinda drop into a folder and expect it to run .
它用于通过编写它们来在运行时加载dll。这是通常用于插件或其他任何你放入文件夹并期望它运行的东西。
Here's a link to some more tutorials as well: Where can I learn about MEF?
这里还有一些指向更多教程的链接:我在哪里可以了解MEF?
#4
0
Yes, you're right, it is not possible to simply unload an assembly (only AppDomains). But I think one of the features of ASP.Net vNext is the ability to have just in-memory assemblies and when you simply alter the source code on the drive it gets automatically compiled and loaded. Therefor a mechanism must exist to unload the previous version.
是的,你是对的,不可能简单地卸载一个程序集(只有AppDomains)。但我认为ASP.Net vNext的一个特性就是能够只拥有内存中的程序集,当你只是改变驱动器上的源代码时,就会自动编译和加载它。因此,必须存在卸载先前版本的机制。
I think they are doing that by simply creating a AppDomain where all assemblies are loaded into again to avoid any cross domain communication. But i don't really know and maybe if you would dig more into the mechanism on how they do this stuff in ASP.NET you maybe find a good solution. More informations about the hot topics from vNext you can maybe also find at Scotts Blog.
我认为他们只是通过创建一个AppDomain来实现这一点,其中所有程序集都被重新加载以避免任何跨域通信。但我真的不知道,也许你会更多地了解他们如何在ASP.NET中完成这些工作的机制,你可能会找到一个很好的解决方案。有关vNext热门话题的更多信息,您也可以在Scotts博客上找到。
#5
0
Well, I've found 2 solutions that work for me, which I would like to share. The first one is to use CollectibleAssembly
and define the types. This is certainly a bit tricky, and a number of restrictions are imposed on this type of dynamic assembies. The other option is to use a scripting language like IronPython
or IronRuby
. Also a great feature of the new Roslyn compiler is that it also provides scripting APIs, not previously available in the .NET framework. What's more, the Roslyn scripting languages tend to look very much like their full-blown equivalents (C# or VB). And I've also found a tiny example of its capabilites.
好吧,我找到了两个对我有用的解决方案,我想分享一下。第一个是使用CollectibleAssembly并定义类型。这当然有点棘手,并且对这种类型的动态组合施加了许多限制。另一种选择是使用像IronPython或IronRuby这样的脚本语言。新的Roslyn编译器的一个很棒的特性是它还提供了以前在.NET框架中不可用的脚本API。更重要的是,Roslyn脚本语言往往看起来非常像它们的完整等价物(C#或VB)。而且我也发现了它的功能的一个小例子。
#1
3
You need some kind of plugin system with well defined interfaces. Then you load at runtime binaries (your plugin *.dll) and create objects from it and then execute methods on it. When you create a system where objects from your plugins must be created through your IPluginManager you have no problem with replacing code at runtime. :)
您需要某种具有良好定义的接口的插件系统。然后加载运行时二进制文件(您的插件* .dll)并从中创建对象,然后在其上执行方法。当您创建一个系统,其中必须通过IPluginManager创建插件中的对象时,在运行时替换代码没有问题。 :)
Or
要么
You have something like a folder with *.cs files which will on demand compiled (in memory) and create the objects you want to use from them and call the methods on them. Which is basically the same like above, without compiling at run time.
你有一个像* .cs文件的文件夹,它将按需编译(在内存中)并创建你想要使用它们的对象并调用它们上的方法。这与上面的基本相同,没有在运行时编译。
From there you can make further improvements.
从那里你可以进一步改进。
EDIT: Like you wrote the only problem without using AppDomain is that once loaded assemblies can't be unloaded. But that's not really a problem.
编辑:就像你写的一样,不使用AppDomain的唯一问题是一旦加载的程序集无法卸载。但这不是一个真正的问题。
#2
1
I don't think you need separate AppDomains: you can dynamically load assemblies within the current AppDomain. And each assembly should probably implement some defined interfaces (depending on your usage). You could use the FileSystemWatcher class, for example, to load/unload assemblies as needed.
我认为您不需要单独的AppDomains:您可以在当前AppDomain中动态加载程序集。每个程序集应该实现一些定义的接口(取决于您的用法)。例如,您可以使用FileSystemWatcher类根据需要加载/卸载程序集。
See http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
请参阅http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx
#3
0
You can have a look at MEF. It stands for: Managed Extensibility Framework .
Here's another article about it MEF on codeproject.
你可以看看MEF。它代表:托管可扩展性框架。这是另一篇关于它在codeproject上的MEF的文章。
It is used to load dll
's in runtime by composing them. This is what is usually used for plugins
or anything else you kinda drop into a folder and expect it to run .
它用于通过编写它们来在运行时加载dll。这是通常用于插件或其他任何你放入文件夹并期望它运行的东西。
Here's a link to some more tutorials as well: Where can I learn about MEF?
这里还有一些指向更多教程的链接:我在哪里可以了解MEF?
#4
0
Yes, you're right, it is not possible to simply unload an assembly (only AppDomains). But I think one of the features of ASP.Net vNext is the ability to have just in-memory assemblies and when you simply alter the source code on the drive it gets automatically compiled and loaded. Therefor a mechanism must exist to unload the previous version.
是的,你是对的,不可能简单地卸载一个程序集(只有AppDomains)。但我认为ASP.Net vNext的一个特性就是能够只拥有内存中的程序集,当你只是改变驱动器上的源代码时,就会自动编译和加载它。因此,必须存在卸载先前版本的机制。
I think they are doing that by simply creating a AppDomain where all assemblies are loaded into again to avoid any cross domain communication. But i don't really know and maybe if you would dig more into the mechanism on how they do this stuff in ASP.NET you maybe find a good solution. More informations about the hot topics from vNext you can maybe also find at Scotts Blog.
我认为他们只是通过创建一个AppDomain来实现这一点,其中所有程序集都被重新加载以避免任何跨域通信。但我真的不知道,也许你会更多地了解他们如何在ASP.NET中完成这些工作的机制,你可能会找到一个很好的解决方案。有关vNext热门话题的更多信息,您也可以在Scotts博客上找到。
#5
0
Well, I've found 2 solutions that work for me, which I would like to share. The first one is to use CollectibleAssembly
and define the types. This is certainly a bit tricky, and a number of restrictions are imposed on this type of dynamic assembies. The other option is to use a scripting language like IronPython
or IronRuby
. Also a great feature of the new Roslyn compiler is that it also provides scripting APIs, not previously available in the .NET framework. What's more, the Roslyn scripting languages tend to look very much like their full-blown equivalents (C# or VB). And I've also found a tiny example of its capabilites.
好吧,我找到了两个对我有用的解决方案,我想分享一下。第一个是使用CollectibleAssembly并定义类型。这当然有点棘手,并且对这种类型的动态组合施加了许多限制。另一种选择是使用像IronPython或IronRuby这样的脚本语言。新的Roslyn编译器的一个很棒的特性是它还提供了以前在.NET框架中不可用的脚本API。更重要的是,Roslyn脚本语言往往看起来非常像它们的完整等价物(C#或VB)。而且我也发现了它的功能的一个小例子。