MEF(Managed Extensibility Framework)使用全部扩展组件

MEF(Managed Extensibility Framework),所在命名空间是System.ComponentModel.Composition.dll。简单来说,MEF是将符合约定(一般是实现接口)的组件的Parts(类、方法和属性可看作是Part)标记为Export特性,再把这些组件放到与可执行程序同目录的Extensions文件夹中,最后通过把Part标记为Import来引用这些组件,从而为我们创建可扩展组件提供了方便。

以球员踢球为例,体验MEF的工作原理和便捷之处。
3

● HelloMEF.Lib,类库,包含了一个接口IPlay,即约定
● HelloMEF.BackPlay,类库,包含了一个实现IPlay接口的类Back.cs
● HelloMEF.FowardPlay, 类库,包含一个实现IPlay接口的类Foward.cs
● Portal,控制台应用程序

□ 可扩展的前提是满足约定,即接口

namespace HelloMEF.Lib
{
    public interface IPlay
    {
        string PlaySoccer(string name, string position);
    }
}

□ HelloMEF.BackPlay类库中的Back.cs实现IPlay接口

→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件

using System.ComponentModel.Composition;
using HelloMEF.Lib;

namespace HelloMEF.BackPlay
{
    [Export(typeof(IPlay))]
    public class Back : IPlay
    {
        public string PlaySoccer(string name, string position)
        {
            return string.Format("我是{0},司职{1},我的主要任务是防守和传球~~", name, position);
        }
    }
}

□ HelloMEF.FowardPlay类库中的Foward.cs实现IPlay接口
→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件

using System.ComponentModel.Composition;
using HelloMEF.Lib;

namespace HelloMEF.FowardPlay
{
   [Export(typeof(IPlay))]
    public class Forward : IPlay
    {
        public string PlaySoccer(string name, string position)
        {
            return string.Format("我是{0},司职{1},我的主要任务是传球和射门~~", name, position);
        }
    }
}

□ 控制台程序

→引用HelloMEF.Lib组件
→引用System.ComponentModel.Composition组件
→在可执行文件所在目录,即输出路径下,创建Extensions文件夹

4

假设,满足约定的一个或多个组件已经方在Extensions文件夹中了,还需要做的大致包括:
→把所有的组件放在Catalog中
→放到CompositionContainer容器中
→在CompositionContainer容器中组合组件
→以Import标记,注入到某个Part上,比如属性上,由程序来决定使用全部或某些组件

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using HelloMEF.Lib;
 
namespace Portal
{
    class Program
    {
        [ImportMany(typeof(IPlay))]
        public IPlay[] Plays { get; set; }
 
        static void Main(string[] args)
        {
            Program p = new Program();
            p.ShowTeam();
            Console.ReadKey();
        }
 
        public void ShowTeam()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog(@".Extensions"));
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
            string name = "";
            string position = "";
            while (true)
            {
                Console.WriteLine("输入球员名称");
                name = Console.ReadLine();
                Console.WriteLine("输入球员位置");
                position = Console.ReadLine();
                foreach (IPlay play in Plays)
                {
                    Console.WriteLine(play.PlaySoccer(name, position));
                }
            }
            
        }
    }
}
 

Extensions文件夹只有HelloMEF.FowardPlay.dll,效果如下:
1

Extensions文件夹中包含HelloMEF.FowardPlay.dll和HelloMEF.BackPlay.dll,效果如下:
2

原文地址:https://www.cnblogs.com/darrenji/p/3737992.html