Good architecture / library for reliable plugin / addon management

We have an application that, as one of its requirements, will accept arbitrary third-party plugins, download them and launch its interface with our home application. We loaded these third-party plugins into our own AppDomains for isolation, and everything works fine.

Until one of the plugins fails with an unhandled exception. In this case, the whole application goes down, although everything that is really affected is one of our additional tools.

We would ideally want to somehow handle the โ€œunhandledโ€ exception, unload the damaged AppDomain, and then simply reload it. The problem is that we cannot find the mechanism in the event handler for the unhandled exception, through which we can throw the exception as "processed". In addition, since plugins have their own user interface components with their own set of user interactions, it would be extremely difficult to โ€œwrapโ€ our interactions with plugins in try / catch / finally blocks.

Are there any frameworks / libraries / programming patterns that can solve this problem? We can do plugins perfectly; what we need helps keep the application running when code in another AppDomain unexpectedly exits.

+7
source share
5 answers

You can use the System.Addin framework (sometimes called MAF ), which is a little difficult to configure correctly, but it is designed to provide isolation (protection against crashes). System.Addin based on removal. Using this environment, you can let plugins work with limited permissions, in the same process or in a different application domain, or even in another process.

If you need full protection against crashes, you may need to use the process separation option. Perhaps this is due to the price of performance.

You can use this code to load addin in another application domain:

 AppDomain addInDomain = AppDomain.CreateDomain("addin domain"); // addInDomain.PermissionSet = ... AddInEnvironment env = new AddInEnvironment(addInDomain); // Activate the add-in IHostView addinInstance = addinToken.Activate<IHostView>(env); Console.WriteLine(addinInstance.DoSomething()); AppDomain.Unload(addInDomain); 

If you want to load the add in another process, for complete isolation:

 AddInProcess process = new AddInProcess(); process.Start(); // Activate the add-in IHostView addinInstance = addinToken.Activate<IHostView>(process, AddInSecurityLevel.Internet); try { // use a catch block, prevent exceptions from the addin crashing the main app Console.WriteLine(addinInstance.DoSomething()); } catch (Exception e) { Console.WriteLine(e); } process.Shutdown(); 

This blog gives a good description of customizing this.

You can combine System.Addin with MEF, these are free toolkits, see this article .

Please note that the System.Addin model can provide protection against crashes, you still have to deal with slowdowns or deadlocks in addin code. Asynchronous use will help here.

+9
source

Looks like you need something similar to OSGi for Java - Is MEF OSGi for .NET? It looks like it can fit the bill.

+1
source
+1
source

I do not think that's possible. I understand that even if you handle the AppDomain.UnhandledException event, the application will still be terminated. The best you can do is to handle the exception, register what you can, save what you can, and terminate gracefully.

+1
source

I assume you have already checked the documentation, but if not the next page

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

provides a lot of information about how unhandled exceptions work. It also mentions several attributes that allow you to fine-tune the behavior.

Unfortunately, I can not give you any advice about your specific situation, since I did not use separate AppDomains in this way. I can say that in my experience with the UnandledException event, the IsTerminating flag is rarely true, and we can almost always recover from an unhandled exception.

0
source

All Articles