Click here to Skip to main content
15,442,578 members
Articles / Programming Languages / C#
Posted 3 Jun 2006


77 bookmarked

Enabling Your Application to Become a Plugin Host

Rate me:
Please Sign up or sign in to vote.
3.56/5 (33 votes)
3 Jun 2006CPOL5 min read
This brief article is a compilation of the .NET mechanisms that allow for discovering and late-binding external code to your application.


Your application may gain a lot of flexibility if you allow yourself and others to add new functionality after deployment. This can be done if you enable your code to host new components that are not yet known at design time, sometimes referred to as Plugins.

In this article, you learn about the very basics of how late binding in C# can do the job, by creating the most primitive skeleton of a plugin and its hosting application.

The Plan

Design Overview

Let's get clear about our goal: we want to write a C# application that invokes operations or uses attributes of components it does not yet know about at the time when the application is written. To be more precise, our app of course has to know what it expects from the plugin component, otherwise it would not know what to do with it in the first place. We will express this expectation in the form of a C# interface.

We must also be more precise in what we mean when we talk about the plugin being a component, which is a term taken from UML or COM. The .NET platform calls physical artifacts like executable applications and reusable libraries assemblies. Our plugin will be such an assembly and contain at least one C# class that implements the interface that our application relies on.

Finally, this plugin interface must be available to both, the application as well as the plugin. To enable creating and building plugins without depending on the application itself, we will put the interface also into a separate assembly. The figure shows the static structure of our setup (for the sake of generality showing a second plugin), eventually leading to three assemblies:

  • The application assembly in the form of an *.exe file
  • The interface assembly in the form of a *.dll file
  • The actual plugin assembly, also in the form of a *.dll file

To Know or Not to Know

What does it mean from a technical point of view that our application will not know the concrete plugin at design time, but is able to invoke its features at runtime? The keyword here is what is referred to as late binding. Instead of statically compiling the program with the known class type of the plugin implementation, we dynamically load the plugin assembly and instantiate the plugin class.

.NET provides numerous variations to perform both of these tasks. We will use one of the simplest and most straightforward forms, where we specify the plugin assembly through its file path and the class to be instantiated from it through its class name. This can be done through a single call to:

System.Activator.CreateInstanceFrom( string assemblyFilepath, string typeName );

The object returned from this method is actually only a handle to the instantiated type that still needs to be unwrapped to reveal the actual object, but we will see this further below. Let's start with the hands-on job in Visual Studio 2005 or its Visual C# Express variant.

Projects Setup

Project Browser

We create a new solution called PluginTest with a new project of the same name. To keep things simple, choose project type Console Application. Then we create the interface project that both the application and all plugins will share. As part of the existing solution, create a new project, this time of type Class Library and call it PluginInterface. The last project, also to be created within the existing solution is for the plugin itself. Again, create a Class Library, and assign it a fake plugin name, e.g. PluginX.

Since the interface project will always be shared between application and plugins, we can add this dependency manually. It is worth noting in the given context that this is a static reference, well known at design time. Therefore, we can already add the PluginInterface assembly to the references section of the two other projects. Of course, this is not possible for the dependency between application and plugin...

Next we add the types. Add an interface to the PluginInterface project (or utilize the existing default class that was created by Visual Studio) and call it IPluginInfo. Rename the generated class in project PluginX to PluginInfo. We will end up with a project structure as shown in the figure, including the two displayed references to the PluginInterface assembly.

Making It Work

Now that the projects have been set up, we will fill the classes and interface with life. The simplest functionality a plugin could possibly provide to its host is to reveal its name. Of course, much more complex tasks can be outsourced through a plugin mechanism, but the name query is enough to show the fundamental mechanism.

Therefore, we define the interface type in the PluginInterface assembly like this:

namespace PluginInterface
    public interface IPluginInfo
        string name { get; }

The implementing plugin in the PluginX project is equally simple, just returning a fixed string:

using PluginInterface;

namespace PluginX
    public class PluginInfo : IPluginInfo
        public string name
                return "Plugin X";

The last piece is now to late-bind the plugin assembly at runtime into the application and to instantiate the corresponding type. As mentioned before, we use the simple approach of matching names. Especially for the plugin's class name, this may look like a cheat. However, it is certainly possible to require your plugin suppliers to follow a certain naming convention for the plugin's namespace and the contained class. If this is not an option, .NET provides quite a number of advanced ways to search a loaded assembly for a type. E.g. it would be possible to look for a class that actually implements the known IPluginInfo interface. But let's go back to our simple approach, which only requires two lines of code. First the assembly is loaded and the plugin class is instantiated by name. The ObjectHandle returned by this call is then unwrapped in the second step, which finally reveals the desired reference to the plugin class. This reference is casted to our IPluginInfo interface, which allows us to subsequently call all the nifty operations defined by it, including the demonstrated name query.

using System.Reflection;
using System.Runtime.Remoting;
using PluginInterface;

namespace PluginTest
    class Program
        static void Main( string[] args )
            ObjectHandle oHandle = Activator.CreateInstanceFrom
		( "..\\..\\..\\PluginX\\bin\\Release\\PluginX.dll",
                "PluginX.PluginInfo" );

            IPluginInfo pluginInfo = oHandle.Unwrap() as IPluginInfo;
            Console.WriteLine( "Loaded plugin's name is: " + );


  • 4th June, 2006: Initial post


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer (Senior) BMW AG
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

GeneralMy vote of 5 Pin
BeeWayDev3-May-12 8:23
MemberBeeWayDev3-May-12 8:23 
GeneralNice tutorial! Pin
APouwels11-May-11 22:48
MemberAPouwels11-May-11 22:48 
GeneralFile Access Permission Problem Pin
WCCheung23-Jul-10 11:41
MemberWCCheung23-Jul-10 11:41 
GeneralVielen dank! Pin
cplas18-Jan-09 8:39
Membercplas18-Jan-09 8:39 
GeneralFantastic!! Pin
firepacket23-Jan-08 13:28
Memberfirepacket23-Jan-08 13:28 
GeneralCall methods in host project Pin
Webtijn29-Jun-07 4:58
MemberWebtijn29-Jun-07 4:58 
GeneralRe: Call methods in host project Pin
Mike Pagel29-Jun-07 21:29
MemberMike Pagel29-Jun-07 21:29 
GeneralThis article Pin
Christopher Stratmann28-Jun-07 4:56
MemberChristopher Stratmann28-Jun-07 4:56 
QuestionRemove a DLL Plugin Pin
alex4uk24-Aug-06 1:28
Memberalex4uk24-Aug-06 1:28 
AnswerRe: Remove a DLL Plugin [modified] Pin
Mike Pagel24-Aug-06 8:25
MemberMike Pagel24-Aug-06 8:25 
GeneralAssembly-level attribute Pin
Alexey A. Popov4-Jun-06 22:10
MemberAlexey A. Popov4-Jun-06 22:10 
GeneralRe: Assembly-level attribute Pin
Mike Pagel6-Jun-06 9:36
MemberMike Pagel6-Jun-06 9:36 
GeneralRe: Assembly-level attribute Pin
Alexey A. Popov7-Jun-06 6:40
MemberAlexey A. Popov7-Jun-06 6:40 
GeneralUnnecessary PropertyInfo Pin
Alexey A. Popov7-Jun-06 6:46
MemberAlexey A. Popov7-Jun-06 6:46 
GeneralRe: Assembly-level attribute Pin
Mike Pagel8-Jun-06 2:29
MemberMike Pagel8-Jun-06 2:29 
QuestionAny source/project code download? Pin
Jun Du4-Jun-06 15:42
MemberJun Du4-Jun-06 15:42 
AnswerRe: Any source/project code download? Pin
Mike Pagel6-Jun-06 9:30
MemberMike Pagel6-Jun-06 9:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.