Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Load a User DLL implementing an AppIn interface

0.00/5 (No votes)
1 Nov 2008 1  
Loading a DLL containing implementations of an interface used as an extension to your application.

Introduction

Sometimes, you need to give a user of your application the chance to implement his own functions without recompiling the full application.

Background

For some projects, I needed the user to load their own implementations of an interface. These classes were used to collect and show some information in my application. The configuration was loaded by the runtime, and contained the name of the loaded and used classes.

So, it was needed to instantiate all these objects by Reflection during runtime.

Using the code

There are three projects in the .NET solution:

  • LoadFromDll -> Contains the main function loading the UserLibrary.
  • Interfaces -> Contains the interface used by the UserLibrary.
  • UserLibrary -> Contains the implementations of the user.

The Interface project is used as a resource in the UserLibrary project. It defines the interface IUserInterface:

public interface IUserInterface
{
    String GetName();
    int Funktion(int a, int b);
}

IUserInterface is used by the implementations that are loaded at runtime. A sample of an implementation looks like:

public class UserClass1 : Interfaces.IUserInterface
{
    public String GetName() { return "Add"; }
    public int Funktion(int a, int b) { return a + b; }
}

In the main functions, all classes implementing IUserInterface are collected:

private static Dictionary<String, Type> nameTypeDict = new Dictionary<string, Type>(); 

[...]

Assembly ass = Assembly.LoadFrom(@"UserLibrary.dll");
foreach (Type t in ass.GetExportedTypes())
{
    //Get all classes implement IUserInterface
    if (t.GetInterface("IUserInterface", true)!=null)
    {
        Console.WriteLine("Found Type: {0}", t.Name);
        nameTypeDict.Add(t.Name, t);//Add to Dictonary
    }
}

Now, you are able to instantiate and use the implementations only by the name of the class:

private static void ExecuteByName(String typeName, int a, int b)
{
    //Create Instance
    IUserInterface o = (IUserInterface)nameTypeDict[typeName].InvokeMember(null,        
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.CreateInstance, 
                null, null, null);
    //Print information and call function
    Console.WriteLine(o.GetName());
    Console.WriteLine(o.Funktion(a, b));
}

Points of interest

I use this code with a configuration file containing the assembly's file name and the order of the loaded classes.

History

  • First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here