How to load plugins in .NET?

◇◆丶佛笑我妖孽 提交于 2019-11-28 03:59:04
Zooba

The following code snippet (C#) constructs an instance of any concrete classes derived from Base found in class libraries (*.dll) in the application path and stores them in a list.

using System.IO;
using System.Reflection;

List<Base> objects = new List<Base>();
DirectoryInfo dir = new DirectoryInfo(Application.StartupPath);

foreach (FileInfo file in dir.GetFiles("*.dll"))
{
    Assembly assembly = Assembly.LoadFrom(file.FullName);
    foreach (Type type in assembly.GetTypes())
    {
        if (type.IsSubclassOf(typeof(Base)) && type.IsAbstract == false)
        {
            Base b = type.InvokeMember(null,
                                       BindingFlags.CreateInstance,
                                       null, null, null) as Base;
            objects.Add(b);
        }
    }
}

Edit: The classes referred to by Matt are probably a better option in .NET 3.5.

As of .NET 3.5 there's a formalized, baked-in way to create and load plugins from a .NET application. It's all in the System.AddIn namespace. For more information you can check out this article on MSDN: Add-ins and Extensibility

cdiggins

Dynamically Loading Plug-ins

For information on how to dynamically load .NET assemblies see this question (and my answer). Here is some code for loading creating an AppDomain and loading an assembly into it.

var domain = AppDomain.CreateDomain("NewDomainName");
var pathToDll = @"C:\myDll.dll"; 
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(pathToDll, t.FullName) 
    as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

Unloading Plug-ins

A typical requirement of a plugin framework is to unload the plugins. To unload dynamically loaded assemblies (e.g. plug-ins and add-ins) you have to unload the containing AppDomain. For more information see this article on MSDN on Unloading AppDomains.

Using WCF

There is a stack overflow question and answer that describe how to use the Windows Communication Framework (WCF) to create a plug-in framework.

Existing Plug-in Frameworks

I know of two plug-in frameworks:

Some people talk about the Managed Extensibility Framework (MEF) as a plug-in or add-in framework, which it isn't. For more information see this StackOverflow.com question and this StackOverflow.com question.

One tip is to load all plugins and such into an own AppDomain, since the code running can be potentially malicious. An own AppDomain can also be used to "filter" assemblies and types that you don't want to load.

AppDomain domain = AppDomain.CreateDomain("tempDomain");

And to load an assembly into the application domain:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(assemblyPath);
Assembly assembly = domain.Load(assemblyName);

To unload the application domain:

AppDomain.Unload(domain);

Yes, ++ to Matt and System.AddIn (a two-part MSDN magazine article about System.AddIn are available here and here). Another technology you might want to look at to get an idea where the .NET Framework might be going in the future is the Managed Extensibility Framework currently available in CTP form on Codeplex.

Basically you can do it in two ways.

The first is to import kernel32.dll and use LoadLibrary and GetProcAddress as you used it before:

[DllImport("kernel32.dll")]

internal static extern IntPtr LoadLibrary(String dllname);

[DllImport("kernel32.dll")]

internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname);

The second is to do it in the .NET-way: by using reflection. Check System.Reflection namespace and the following methods:

First you load the assembly by it's path, then get the type (class) from it by it's name, then get the method of the class by it's name again and finally call the method with the relevant parameters.

The article is a bit older, but still applicable for creating an extensibility layer within your application:

Let Users Add Functionality to Your .NET Applications with Macros and Plug-Ins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!