I am working on an application that uses a plug-in architecture to expand it’s functionality. What is the best way to load WPF UIs from a plug-in?
I will have a listbox listing all of the available plug-ins. When a plug-in is selected, a WPF UI defined in the plug-in should be displayed in a ContentControl. The options I have thought of include:
- Require a
UserControlto be created that implements a specific interface. I am thinking this would make it easy for plug-in creation. Implement an interface and you are good to go. My question with this method is how to dynamically load theUserControlinto aContentControl. Also, since I am using the MVVM design pattern it seems that aDataTemplatewould be preferred over aUserControl. - Allow a
DataTemplateto be loaded from the plug-in. I believe this would require the plug-in to contain a XAML file named a certain way. My application would read theDataTemplateinto my resource dictionary like shown in this question. I have seen quite a few questions similar to this, except they usually only need to load one additional, predefined assembly to getDataTemplatesfrom. This problem would require any number of unknown assemblies to be searched forDataTemplates.
If I choose the second option, I think I could select the DataTemplate similarly to how this answer describes.
Which method do you think is better? Or do you have a better way to accomplish this?
I did something similar like mentioned with
DataTemplates. I used MEF to load plugins and then loaded aDictionarywith a reference to theViewModelandViewat startup. The plugin isbuilt using 3 main components.IBasePlugin.cs
This simple interface allows us to create a skeleton for the plugin. This will only contains the very basics, as this is what we will use to
Importplugins to our main application usingMEF.Plugin.cs
The next part is the
Plugin.csfile. It contains all the properties of our plugin, as well as all the necessary references; such as to ourView&ViewModel.View.xaml
This is a
DataTemplatecontaining a Reference to the pluginViewandViewModel. This is what we will use forPlugin.csto load into the main application, so that the application andWPFwill know how to bind everything together.We then use MEF to load all the plugins, feed them to our Workspace
ViewModelresponsible of handling the Plugins, and store them in anObservableCollectionthat will be used to display all the available plugins.The code we use to load plugins can look something like this.
Once both the
DictinoaryandViewModelhas been loaded from our Plugin into our application we can display the collection using for example aTabControl.I also gave a similar answer here as well with some additional details that you might find interesting.