分享

C Sharp与.net学习笔记(四)

 kittywei 2012-01-31

接前面MAF,看看MEF插件框架(它是.NET4的组成部分,所以装个Visual C#2010 express)

和 MAF 比起来,这个易用性太高了。只需要定义一个接口,然后Import、Export、Compose就行了...

例子

动手试两个简单的例子:

  • 定义接口 interface.cs

public interface IOperation
{
    int Operate(int left, int right);
}
  • 使用接口 program.cs
    • Import
    • Compose

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();
        }
    }
}
  • 实现接口 add.cs
    • Export

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,此时,定义一个额外的接口保存插件接口相关参数

  • interface.cs

public interface IOperation
{
    int Operate(int left, int right);
}

public interface IOperationID
{
    char ID { get;}
}
  • program.cs

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多