.NET 添加了可能符合要求的“托管插件框架”。它具有以下特点:
-
隔离。插件在自己的AppDomain中运行如果需要的话,甚至是他们的自己的流程如果您需要这种程度的隔离。
-
契约沟通。您设置合同,这是您分发给插件作者的唯一内容。他们不需要了解您申请的任何其他方面。
-
发现。有一个内置机制,可以从充满程序集的文件夹中嗅出插件。
-
Security。当您加载插件时,会自动应用 CASPOL 集。有一些内置选项可以使这变得简单(请参阅AddInSecurityLevel 枚举).
大多数隔离方法也会限制通信和 UI 集成。 MAF 试图绕过这些限制。它要求您设置合同通信管道,但将执行您通常需要自己完成的大部分工作。
一个示例是将在两个单独进程中运行的 UI 片段拼接在一起(这很神奇),或者能够跨 AppDomain 或进程引发事件。这些事情都很重要,但 MAF 在这方面有很大帮助。
Sample
这是一个简单的例子。作为“Shell”作者,您将向插件作者提供合同。这是一个典型的合约(它只是一个抽象类):
public abstract class Calculator
{
public abstract double Add(double a, double b);
public abstract double Subtract(double a, double b);
public abstract double Multiply(double a, double b);
public abstract double Divide(double a, double b);
}
如果插件作者想要编写一个插件,他们只需对该合约进行子类化并添加“Addin”属性:
[AddIn("Sample Calculator AddIn", Version="1.0.0.0")]
public class SampleCalculatorAddIn : Calculator
{
public override double Add(double a, double b)
{
return a + b;
}
public override double Subtract(double a, double b)
{
return a-b;
}
public override double Multiply(double a, double b)
{
return a * b;
}
public override double Divide(double a, double b)
{
return a / b;
}
}
以下是加载这些插件并与它们交互的方法:
// In this sample we expect the AddIns and components to
// be installed in the current directory
String addInRoot = Environment.CurrentDirectory;
// Check to see if new AddIns have been installed
AddInStore.Rebuild(addInRoot);
// Look for Calculator AddIns in our root directory and
// store the results
Collection<AddInToken> tokens =
AddInStore.FindAddIns(typeof(Calculator), addInRoot);
// Ask the user which AddIn they would like to use
AddInToken calcToken = ChooseCalculator(tokens);
// Activate the selected AddInToken in a new AppDomain set sandboxed
// in the internet zone. You can find out what this gives access
// to by running "mscorcfg.msc", but essentially this will limit
// any access to the filesystem and other obvious OS services.
// Use of reflection is also very limited in this zone.
Calculator calculator =
calcToken.Activate<Calculator>(AddInSecurityLevel.Internet);
// Run the read-eval-print loop
RunCalculator(calculator);
这就是要点。显然还有更多的内容,但你明白了。
进一步阅读
很好的介绍文章
https://web-beta.archive.org/web/20140820145919/http://msdn.microsoft.com/en-us/magazine/cc163476.aspx
MSDN 上的概述
http://msdn.microsoft.com/en-us/library/bb384200.aspx
Codeplex 上的 System.Addin(大量示例)
http://www.codeplex.com/clraddins
Tools
管道建设者(有助于生成 shell 和插件之间的通信管道)
System.Addin 的 Fx-Cop 规则