接前面MAF,看看MEF插件框架(它是.NET4的组成部分,所以装个Visual C#2010 express)
和 MAF 比起来,这个易用性太高了。只需要定义一个接口,然后Import、Export、Compose就行了...
动手试两个简单的例子:
public interface IOperation { int Operate(int left, int right); }
using System; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; class Program { [Import(typeof(IOperation))] public IOperation op; private CompositionContainer container; private Program() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(".")); container = new CompositionContainer(catalog); container.ComposeParts(this); } static void Main(string[] args) { Program p = new Program(); Console.Write("Input two number.\n%> "); string line = Console.ReadLine(); while (line != "q") { string[] nums = line.Split(' '); try { int res = p.op.Operate(int.Parse(nums[0]), int.Parse(nums[1])); Console.Write("{0}\n%> ", res.ToString()); } catch { Console.Write("Error!\n%> "); } line = Console.ReadLine(); } } }
using System.ComponentModel.Composition; [Export(typeof(IOperation))] class Add : IOperation { public int Operate(int left, int right) { return left + right; } }
编译:
E:\Test> csc /target:library interface.cs E:\Test> csc /r:System.ComponentModel.Composition.dll;interface.dll program.cs E:\Test> csc /r:System.ComponentModel.Composition.dll;interface.dll add.cs
前面的例子使用Import只能导入一个插件(对应一个Export),如果有多个Export,则运行时会抛出异常。
如果需要导入多个,使用 ImportMany,此时,定义一个额外的接口保存插件接口相关参数
public interface IOperation { int Operate(int left, int right); } public interface IOperationID { char ID { get;} }
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; class Program { [ImportMany] IEnumerable<Lazy<IOperation, IOperationID>> operations; private CompositionContainer container; private Program() { var catalog = new AggregateCatalog(); //catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly)); catalog.Catalogs.Add(new DirectoryCatalog(".")); container = new CompositionContainer(catalog); container.ComposeParts(this); } static void Main(string[] args) { Program p = new Program(); foreach (Lazy<IOperation, IOperationID> i in p.operations) { Console.WriteLine("{0} {1}", i.Metadata.ID, i.Value.Operate(886, 2).ToString()); } } }
[Export(typeof(IOperation))] [ExportMetadata("ID", '+')] class Add : IOperation { public int Operate(int left, int right) { return left + right; } } [Export(typeof(IOperation))] [ExportMetadata("ID", '-')] class Subtract : IOperation { public int Operate(int left, int right) { return left - right; } } ...
这些Export非常灵活,可以在当前的dll内,也可以在exe内,...
运行结果:
E:\Test> program.exe + 888 - 884 / 443 * 1772