1

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.

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).

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?

ax1mx2
  • 654
  • 1
  • 11
  • 23

5 Answers5

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. :)

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.

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.

user743414
  • 936
  • 10
  • 23
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.

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

DvS
  • 1,025
  • 6
  • 11
  • 2
    You can't _unload_ an assembly from an AppDomain, though; that's why separate AppDomains are needed if you want to unload anything (at which point you unload the entire AppDomain). – Aasmund Eldhuset Sep 10 '14 at 12:08
  • You're right. It's necessary to unload the whole AppDomain to 'unload' one assembly. – DvS Sep 10 '14 at 13:49
0

You can have a look at MEF. It stands for: Managed Extensibility Framework .
Here's another article about it MEF on codeproject.

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 .

Here's a link to some more tutorials as well: Where can I learn about MEF?

Community
  • 1
  • 1
Noctis
  • 11,507
  • 3
  • 43
  • 82
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.

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.

Oliver
  • 43,366
  • 8
  • 94
  • 151
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.

ax1mx2
  • 654
  • 1
  • 11
  • 23