Simple Plugin System based on Ninject and MVVM Light
My goal was to develop a simple but useful plugin system for my future developments. I wanted to keep/to have:
- Ninject power and flexibility
- Smooth animations
- Modularity (development & code)
- Fast “menu” system
The PluginSystem assembly contains the plugin base class, the view model base class and an animated content control.
PluginBase class :
This class force plugins to expose a user interface, an name (for menu printing in this case) and force overriding OnActivate and OnDeactivate methods.
PluginViewModelBase class :
This class is a simple layer over ViewModelBase defined in MVVM Light. The main difference is that it embeds the reference of the parent plugin. With this reference, the plugin can easily access to injected values for example.
AnimatedContentControl class :
This usercontrol works like a commn ContentControl. There is one difference : if you change the content, it will animate it.
You can set AnimatedContent for the content, Delay, EasingFunction and Transition properties to customize the transition when you change the content.
Main application side
You can use the plugin system to get a dynamic menu:
- You can create a Ninject module for declaring plugin bindings.
- Once done, we get all registered plugins by using Ninject Kernel
- You set the list in your viewmodel
- You bind the list to the view
Last step is to bind the selected item’s user control to a content control (or an animated content control).
You can also use the plugin system to get static region system.
Defining a new Plugin
You need to create a new class library. Include some WPF libraries (System.Xaml, PresentationCore, PresentationFramework) and create a plugin definition file and a pluginVM file.
In this plugin file sample, you can set the “MainPart” property, create the view model and set it to the datacontext. Here is a sample:
With this system you can keep “blendability” by using “Sample data” system from Blend. You will have your view model with design mode detection and capability to set custom data.
Ninject power and flexibility
Based on Ninject system, you keep all the power of Ninject. For example :
This module defines 3 plugins but also define sorting parameters based on “Name”
You can use this module for extracting only “FirstScreenable” plugins
(Plugin3 is a dependency for Plugin2 it must not be printed on the first screen)
On the other hand, you can rely on Ninject to inject something else than plugins.
Thanks to the AnimatedContentControl, if you change the “AnimatedContent” property, you automatically start an animation. You can also see/try these animations inside Blend.
Modularity (development & code)
As you can see, the main application is perfectly separated from plugins. Each team can work on a plugin without interact with other plugins.
Why not using PRISM
I have tried Prism during 20 minutes and I was not able to create a simple plugin system based on it. Moreover Prism4 documentation pdf file is more than 352 pages (too much to read for a simple modularity system). One of the best practice is KISS, keep it stupid simple! By the way, this simple plugin system took me less than 30 minutes to create !
All sources are available for WPF here : PluginSystem.zip Contact me if you need a port in Silverlight 🙂
4 réflexions sur « Simple Plugin System based on Ninject and MVVM Light »
I stumbled upon you plugin system while playing around with Ninject for the first time. First off, I love the framework itself. Unfortunately, when I try to load the MainWindow.xaml file in Visual Studio I get an exception « universe cannot resolve assembly: Microsoft.Expression.Interactions, Version=126.96.36.199, Culture=neutral, PublicKeyToken=31bf3856ad364e35 ». I’ve tried switching out references for the ones in the official Blend SDK but it doesn’t seem to work.
The application builds fine but it’s hard to design XAML without a design view. The plugins load fine. It’s just the MainWindow that won’t load in design view. I’d love to experiment with this system more and would greatly appreciate it if you could provide any insight into my problem.
I have done a stupid test, i have downloaded the zip, extracted it, opened it with visual studio 2012 (the only one i have now) and open the MainWindow in Visual Studio editor.
Every seem to work :/
Here is a snapshot : http://www.alphablog.org/?attachment_id=948
Can you check for « unblocking » all dll files in you extraction path ? Moreover, everithing *should* work with the provided assemblies. Try with to umblock them at the first time. After that you should try with others « interaction.dll »
Keep me informed of your progression.
All files are unblocked. I’ve tried creating a new project, importing the plugins and plugin system, and creating a new WPF application using the bulk of the code included in your original WPF application. Everything builds fine but I’m still getting the same error. I’ve tried switching out the references for the ones included in the Blend SDK too and that doesn’t appear to work either.
I’m currently running Visual Studio 2010 along with Expression Blend 2 (haven’t actually gotten to use it yet as I only recently obtained a copy of it). I’m using .Net 4.0. Could it be that the project is incompatible with my current setup?
Here’s a screencap of the full error: http://imgur.com/RiiQsEx
Blend 2 is probably not enough and should be the problem. You can try to install the Blend 4 SDK (http://www.microsoft.com/en-us/download/details.aspx?id=10801) and see if it works (should install needed assemblies in you program files and maybe in the appdomain).
Otherwise, if you are able to get Visual Studio 2012, Blend is provided in one of the last updates.
Say me if it works 🙂