Click here to Skip to main content
11,483,586 members (68,591 online)
Click here to Skip to main content

Dynamic Load .NET Assembly

, 10 Oct 2013 MIT 22.8K 1.3K 32
Rate this:
Please Sign up or sign in to vote.
Example implementation of dynamic assembly loading in C#

Introduction

Dynamic library loading is nothing new in native C++. In Microsoft Window’s implementation, this capability is realized with the use of Dynamic Link Library (DLL). This feature greatly expands the flexibility of an application where new features can be added / modified in the form of plug-in without the need to recompile the entire application. Similar capability is provided in .NET framework to dynamically load assemblies which make plug-in development for .NET based application possible. Moreover, dynamic assembly loading that .NET framework provides is much more powerful than native C++ DLL.

Wikipedia: plug-in is a software component that adds a specific feature to an existing software application.

Overview

Dynamic loading is only possible only when application and component are talking the same language. In such, both application and plug-in component need to communicate with each other using an agreed interface. The content of this interface cannot be changed for the entire lifetime, modifying the content of this interface required the application and all the components to be completely recompiled. See image below:

Implementation

An example of dynamic assembly loading projects is created as shown below for further discussion. This example is coded in C# using Visual Studio 2010 where both the application and plug-in assemblies are referenced to PluginInterface.dll.

  • DynamicLoadAssembly: An application created to test dynamic load capability in .NET framework
  • PluginInterface: Bridge that link between application and plug-in assemblies
  • Plugin_Sum, Plugin_Multiplier, Plugin_Calculation: Plug-in assemblies which implement IPlugin interface in PluginInterface.dll

The demo application contains 2 parts: Simple Test and Advance Test where Simple Test will load from a defined assembly whereas Advance Test will discover and load selected assemblies in the Plugins folder. Besides, a build configuration named “NewPlugin” is created to simulate plug-in development where new plug-in is created without recompiling the main application.

IPlugin Interface

The IPlugin interface is no different from any ordinary interface. It may contain property, methods (function) and events. Since the main application has no visibility of the classes implemented in plug-in assemblies, IPlugin is the only access between application and plug-in assemblies.

public interface IPlugin
{
    string Name {get; }
    string GetDescription();
        
    double GetLastResult { get; }
    double Execute(double value1, double value2);

    event EventHandler OnExecute;

    void ExceptionTest(string input);
} 

Load Assembly

As you can see, plug-in assemblies are not referenced by the main application except PluginInterface. Assembly loading is done by using LoadAssembly in System.Reflection namespace. In this example, we assume that each plug-in assembly contains only one class that implements the IPlugin interface. Theoretically, it is possible to have more than one class in an assembly which implement the IPlugin interface, we leave it for you to explore further.

private PluginInterface.IPlugin LoadAssembly(string assemblyPath)
{
    string assembly = Path.GetFullPath(assemblyPath);
    Assembly ptrAssembly = Assembly.LoadFile(assembly);
    foreach (Type item in ptrAssembly.GetTypes())
    {
        if (!item.IsClass) continue;
        if (item.GetInterfaces().Contains(typeof(PluginInterface.IPlugin)))
        {
            return (PluginInterface.IPlugin)Activator.CreateInstance(item);
        }
    }
    throw new Exception("Invalid DLL, Interface not found!");
} 

Once the assembly is successfully loaded into the application, it can be used just like a normal class instance regardless of whether it is a function call or an event subscription. An example of event subscription on loaded assemblies is shown as below:

currPlugin = LoadAssembly(".\\Plugins\\" + cbAssemblies.Text + ".dll");
currPlugin.OnExecute += new EventHandler(currPlugin_OnExecute); //Subscribe Event. 

Limitation

Despite its high flexibility, there is one limitation in dynamic assemblies loading where there is no way to unload the loaded assemblies until the main application is terminated, even with the System.AppDomain will not release the loaded assembly after AppDomain.Unload is called.

Exception Handling

Exceptions can traverse from loaded assemblies to main application without much problem. The same try ... catch block is sufficient to handle exception raised from assembly unlike native C++ DLL where errors are normally returned as error codes and error messages.

History

  • 10-Oct-2013: Initial release (Version 1.0.0)

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Code Artist
Software Developer (Senior)
Malaysia Malaysia

Comments and Discussions

 
GeneralBrilliant! Pin
_onTy_19-Feb-14 0:13
member_onTy_19-Feb-14 0:13 
GeneralMy vote of 5 Pin
_onTy_18-Feb-14 21:06
member_onTy_18-Feb-14 21:06 
QuestionLoading plugin assemblies Pin
Rohit Taralekar27-Nov-13 2:12
memberRohit Taralekar27-Nov-13 2:12 
AnswerRe: Loading plugin assemblies Pin
Code Artist27-Nov-13 3:44
memberCode Artist27-Nov-13 3:44 
Questionunload and suggestion Pin
giammin10-Oct-13 7:00
membergiammin10-Oct-13 7:00 
AnswerRe: unload and suggestion Pin
Code Artist11-Oct-13 4:25
memberCode Artist11-Oct-13 4:25 
GeneralRe: unload and suggestion Pin
giammin11-Oct-13 4:32
membergiammin11-Oct-13 4:32 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150520.1 | Last Updated 10 Oct 2013
Article Copyright 2013 by Code Artist
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid