Introduction
This article will describe how to implement a simple Plugin-system into your C#-Application which can be very useful for several situations your tool has to implement different behavior. This code snippet will only make use of standard .NET classes which are built-in the Microsoft Framework! No 3rd party tools are needed!
Background
Since I started developing C#-Desktop-Applications about 4 years ago I really ran across several problems. One was, to implement a stable plug-in system with which you could easily spread code and functionality. One big problem was, that no one nowhere had a good tutorial on how to build this. So
I decided to write my own, first tutorial in English. So please be gentle with my grammar.
Using the code
The .NET Framework offers two possibilities to load assemblies to the current AppDomain
. The following code uses the same functionality Visual Studio has
when you're adding a new reference to your project. The code to include an assembly uses the System.Reflection
namespace and looks as following:
Assembly.LoadFrom(@"YourPathToTheDLL");
Now, the assembly is loaded into your application but you can't really use anything in it because normally you don't really know what functionality the plug-in offers.
Also, it's pretty easy to access a DLL in a normal executable but the way back can be very annoying.
Now, to access the DLL, we need its assembly name which should be equal to the main-namespace of it. Unfortunately, there is no way to get the default namespace
of a dynamically added assembly in C#. One possibility is now to always expect the plug-in to have the same namespace as the application we're loading it in.
But that doesn't matter at the moment. Once we've loaded our plug-in, we start using it via Reflection, which goes as follows.
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type t in a.GetTypes())
{
if (t.GetInterface("MyFunctionInterface") != null)
{
try
{
MyFunctionInterface pluginclass = Activator.CreateInstance(t) as MyFunctionInterface;
pluginclass.doSomething();
return;
}
catch
{
}
}
}
}
Easy, right? Working with plug-ins is actually no problem if you understand how easy you can write dynamic code.
Points of Interest
There is also a possibility in the System.Reflection
to load only the bytes of a DLL. By now, I haven't really had a chance of using
it because I can't really imagine a scenario where this would be more useful than linking to the location of the file.
History
- Version 1.0.0.0: Initial with all the information and a working .NET Solution to show how plug-ins can work!