65.9K
CodeProject 正在变化。 阅读更多。
Home

加载实现 AppIn 接口的用户 DLL

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.53/5 (8投票s)

2008年11月2日

CPOL

1分钟阅读

viewsIcon

46513

downloadIcon

546

加载包含作为应用程序扩展的接口实现的 DLL。

引言

有时,您需要让应用程序的用户有机会实现自己的函数,而无需重新编译整个应用程序。

背景

对于某些项目,我需要用户加载他们自己实现的接口。这些类用于在我的应用程序中收集和显示一些信息。配置由运行时加载,并包含加载和使用的类的名称。

因此,需要在运行时通过反射实例化所有这些对象。

使用代码

该 .NET 解决方案包含三个项目

  • LoadFromDll -> 包含加载 UserLibrary 的主函数。
  • Interfaces -> 包含 UserLibrary 使用的接口。
  • UserLibrary -> 包含用户的实现。

接口项目用作 UserLibrary 项目中的资源。它定义了接口 IUserInterface

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

IUserInterface 由运行时加载的实现使用。一个实现的示例如下

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

在主函数中,收集了所有实现 IUserInterface 的类

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
    }
}

现在,您只需通过类名即可实例化和使用这些实现

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));
}

关注点

我使用此代码与包含程序集文件名和加载类顺序的配置文件。

历史

  • First version.
© . All rights reserved.