加载实现 AppIn 接口的用户 DLL






3.53/5 (8投票s)
加载包含作为应用程序扩展的接口实现的 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.