6

For regular assemblies one can use MEF to load assemblies dynamically. If a live update is required of those assemblies, the recommendation is to use AppDomains to host the dynamic assemblies (potentially one can use Managed Add-in Framework (MAF)). When requiring an update, the appdomain is stopped, the assemblies are updated and the appdomain is reloaded.

What about assemblies that are loaded by ASP .NET that contain that code behind classes? How can I update them without forcing a restart of the main appdomain. Is it possible to host some of my pages in a dynamic appdomain? How would you do that? Can this appdomain share login token and authentication stuff so the user doesn't have to re-login?

Thanks

Mark
  • 5,223
  • 11
  • 51
  • 81

2 Answers2

2

MEF doesn't support AppDomain isolation, so unfortunately, even during recomposition, those assemblies that had previously been loaded are still loaded in the main web application AppDomain. There are two things you'd need to battle in ASP.NET:

  1. Any changes to physical files (e.g. .aspx, .cshtml, etc), or any changes to configuration files (.config), or any changes to the \bin directory will cause the application to be recycled. This is due to two things, file monitoring of pages/configs, and file monitoring of the \bin directory (which is because by default ASP.NET uses shadow copying of files - this is recommended).

  2. To use MEF in another AppDomain would require a hideous amount of cross-domain communication, either through serialisation or MarshalByRef, which I just don't think would ever be a clean implementation. Not sure how you would trigger BuildProvider instances used to dynamically compile your pages in another AppDomain either.

I'm wondering if you're thinking about this too much. Since IIS6, HTTP.SYS has managed the routing of incoming requests to the appropriate website, this is handled at the kernel level. Even if the main application did restart (which there are a variety of reasons why it could), no requests will be dropped, it would simply queue waiting for a new worker process before passing the request on. Sure, from the user's point of view, they may notice some idle time waiting for the new application to restart, but realistically, how often are you going to be making these changes?

A lot of application design suffers from over-engineering. You may want to design for every scenario, but realistically it is easier to maintain a system which is simple but extensible. In my opinion, wanting to do what you have specified would be classed as over-engineering. Keep it simple.

Matthew Abbott
  • 60,571
  • 9
  • 104
  • 129
  • So your recommendation in a nutshell then is to just recycle the pool and then it will reload the new assemblies? Am i understanding you correctly? – Mark Sep 29 '11 at 14:40
  • 1
    In a word, yes. It might seem like a disappointing answer for you, but ASP.NET applications are designed to run this way. When you're planning the featureset for your application, its worth considering if the feature you are designing is for the most common use cases or not. Does that make sense? – Matthew Abbott Sep 29 '11 at 14:57
  • I had the idea of creating a sub web application (nested web applications) so that i can recycle the child application and not the parent. What do you think about that? It might be a bit more work but it does give me more flexibility does it not? – Mark Oct 03 '11 at 17:43
0

Using the session "StateServer" will preserve your authentication between app pool recycles (caused by file updates).

For your actual question:

  • Create a folder outside of your website that your app pool has access to.
  • Put your new assemblies in there
  • Have a Task/Thread/Web Service that reads the folder and loads the assemblies into the current App Domain
    • The newer version of the assembly should take precedence when an instance is created

I guess your question is saying this method doesn't work? What error are you getting...

Louis Ricci
  • 20,804
  • 5
  • 48
  • 62