views:

81

answers:

1

(I know about the other MEF/MAF questions but this is a more specific problem)

I want to create a WPF application that will basically be just a simple add-in host, GUI and settings. All of the actual work will be done by one or more plugin(s). They don't need to communicate between each other, the main application will send user input/commands to them and they will return some results (for example, WPF UI elements to render).

Now, since the core of the application will be based on plugins I need to pick a good way to manage them. I want to be able to load/unload/reload them at runtime (for example when an update is found and downloaded). They should probably run in own application domain and/or process for stability and safety.

From some research and experiments I came to three options:

  • System.Addin (MAF): It seems this can do everything I need. There is pipeline that allows multiple versions of API to be run at the same time for compatibility etc. But unless I'm missing something I need to create the API several times - host and plugin views, contract and two adapters for the contract. Also there is little (compared to MEF) information and resources around and most articles are few years old. I'm worried this is slowly dying and would rather not use it for a new project.

  • MEF: This one seems simpler, but it also feels like there is a lot of magic that I can't control, and the layers aren't separated as much as in MAF. I want just a small library you can link to a new project, implement the interface and the plugin is done.

  • Manual loading: The last option would be to manually scan folder for .dlls, use reflection to find plugin classes and create instances. While it is doable, I would rather use some framework than manually load assemblies, create separate process/appdomain etc.

So, which one would be best for this kind of application, or is there something that I've missed?

+4  A: 

MEF is definitely the simplest option of the three. It was really designed with this exact scenario (extensible applications) in mind.

It's actually the "plugin" mechanism used by Visual Studio, which is a WPF application. All you need to do is have your "plugin" implement an interface or derive from a known base class, and add the [Export] attribute. Provided it's assembly is added to your main application's catalog, that type can be [Import]ed by the main application in one step. There is very little work involved in making this work.

It would be my recommendation, unless there is a strong reason to go with a different option. MAF has more isolation support, but is much more difficult to use, and most of the isolation features will not be usable in a WPF application, since the UI in WPF can't really be isolated code in any case.

Reed Copsey
"...since the UI in WPF can't really be isolated..." Not sure what you mean. I need the application to return some UI, for example a button. That will be rendered by the main app but it can have callback back to the plugin. Is it possible to make the plugin run in different appdomain to prevent it from crashing the whole application and maybe provide some isolation for low-trust plugins?
lacop
@Iacop: I'd use MEF for this. You can't really isolate the UI in a separate AppDomain, since it needs to be usable by your shell (that was what I meant). If you're doing this for UI extensibility, the AppDomain isolation provided by MAF is unusable, since a UI always exists in the Single main AppDomain (in WPF), and can't cross AppDomains.
Reed Copsey
If you're using MAF for purely algorithmic plugins, that don't have UI code, it's possible to isolate the plugin into a separate AppDomain - but with UI extensibility, this doens't work - so you lose the single advantage to MAF - which is why I'd say go with MEF (it's much more flexible, better supported, easier to use, etc...)
Reed Copsey