插件注册没有实例化插件类

时间:2012-08-27 19:48:01

标签: c# .net design-patterns plugins

我需要为我们的应用程序设计一个简单的插件框架(.NET,WinForms 3.5)。

扩展点将是用户可以“挂钩”使用插件的几个应用程序事件/场景,以执行特定操作。

我希望这种方式起作用的方式是:

  1. 有一个插件文件夹,用户可以在其中放置插件DLL(包含从特定基类派生的类型的程序集/以某种方式标记)。

  2. 让我的应用程序插件系统找到这些文件并注册它们以供以后使用。

  3. 在适当的时间调用正确的插件(例如:OnException,OnLog等)。

  4. 如果我在注册时创建插件对象(new it up),DLL将被加载到进程内存中。

    我正在寻找一种简单的方法来进行注册,并且只在需要时“懒得”加载插件程序集(如果需要的话)。

2 个答案:

答案 0 :(得分:1)

你有几个选择 - 如果你有能力,你可以要求每个插件提供一个清单或一些描述自己的文件,然后你可以检查所有的清单并在必要时加载适当的插件。这避免了检查程序集,但它确实需要清单和程序集之间的一致性,这可能很棘手。

否则,正如您所指出的那样,检查插件程序集会将其加载到内存中。我发现避免这种情况的唯一方法是将它们加载到单独的AppDomain中,检查它们并捕获必要的信息,然后卸载AppDomain。有一个例子可以在某处为PRISM做这个(我可以尝试跟踪它),但我不确定你正在使用什么框架(MEF,MAF,PRISM,IoC等)。

答案 1 :(得分:1)

在新AppDomain中加载每个候选程序集,反映其类型并最终卸载AppDomain的替代方法,您可以尝试Mono.Cecil。然后你必须做这样的事情:

AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assemblyPath); 

foreach (TypeDefinition td in ad.MainModule.GetTypes()) 
{ 
    if (td.BaseType != null && td.BaseType.FullName == "MyNamespace.MyAddInBase") 
    {         
        return true; 
    } 
} 

然后,您可以使用Assembly.LoadForm加载正确的程序集,最后使用适合您需要的Activator.CreateInstance重载来创建加载项的实例。