C# 插件注册而不实例化插件类
我需要为我们的应用程序(.NET,WinForms 3.5)设计一个简单的插件框架 扩展点将是几个应用程序事件/场景,用户可以使用插件“钩住”这些事件/场景来执行特定操作 我希望这样做的方式是:C# 插件注册而不实例化插件类,c#,.net,design-patterns,plugins,C#,.net,Design Patterns,Plugins,我需要为我们的应用程序(.NET,WinForms 3.5)设计一个简单的插件框架 扩展点将是几个应用程序事件/场景,用户可以使用插件“钩住”这些事件/场景来执行特定操作 我希望这样做的方式是: 有一个插件文件夹,用户将在其中放置插件DLL(包含从特定基类派生的类型/以某种方式标记的类型的程序集) 让我的应用程序插件系统找到这些文件并注册以备以后使用 在正确的时间调用正确的插件(例如:OneException、OnLog等) 如果我在注册时创建plugin对象(new-it-up),DLL将加载
我正在寻找一种简单的注册方法,并且在需要时(如果需要的话)只“惰性地”加载插件程序集。你有几个选项可以这样做-如果你可以,你可以要求每个插件提供一个清单或其他描述其自身的文件,然后,您可以检查所有清单,并在必要时加载适当的插件。这避免了检查程序集,但它确实需要清单和程序集之间的一致性,这可能很棘手
否则,正如您所指出的,检查插件程序集将把它加载到内存中。我发现避免这种情况的唯一方法是将它们加载到单独的
AppDomain
,检查它们并捕获必要的信息,然后卸载该AppDomain
。在某个地方有一个为PRISM执行此操作的示例(我可以尝试跟踪它),但我不确定您使用的是什么框架(MEF、MAF、PRISM、IoC等)。除了在新的AppDomain中加载每个候选程序集、反映其类型并最终卸载AppDomain之外,您还可以尝试。然后,您必须执行以下操作:
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assemblyPath);
foreach (TypeDefinition td in ad.MainModule.GetTypes())
{
if (td.BaseType != null && td.BaseType.FullName == "MyNamespace.MyAddInBase")
{
return true;
}
}
然后,您可以使用重载加载正确的程序集,并最终使用符合您需要的重载创建外接程序的实例。可能与主题无关,但为什么要进行惰性加载插件的工作呢?为自己节省一两秒钟的启动时间似乎并不值得。