在"MEF(Managed Extensibility Framework)使用全部扩展组件"中,客户端应用程序调用了所有的扩展组件,而且如果有新的扩展组件加入,必须先关闭程序,再重新启动才可以调用所有组件。

本篇体验使用MEF的ExportMetadata特性,有选择性地使用某些扩展组件,使用Lazy<>,让客户端程序延迟动态加载组件,即使不关闭应用程序,也能调用所有组件。

 

● StudentMEF.Lib, 类库,包含接口IStudent.cs
● StudentMEF.One,类库,包含实现IStudent的类One.cs
● StudentMEF.Two,类库,包含实现IStudent的类One.cs
● StudentMEF.Client,控制台程序

 

□ 所有扩展满足的约定是

namespace StudentMEF.Lib
{
    public interface IStudent
    {
        string GetName();
        int GetScore();
    }
}

 

□ StudentMEF.One类库

→ 需引用StudentMEF.Lib组件
→ 需引用System.ComponentModel.Composition组件

 

using System.ComponentModel.Composition;
using StudentMEF.Lib;

namespace StudentMEF.One
{
    [Export(typeof(IStudent))]
    [ExportMetadata("Type","ONE")]
    public class One : IStudent
    {
        private string _Name;
        private int _Score;

        public One()
        {
            _Name = "jack";
            _Score = 80;
        }
        public string GetName()
        {
            return _Name;
        }

        public int GetScore()
        {
            return _Score;
        }
    }
}

 

□ StudentMEF.Two类库

→ 需引用StudentMEF.Lib组件
→ 需引用System.ComponentModel.Composition组件

 

using System.ComponentModel.Composition;
using StudentMEF.Lib;

namespace StudentMEF.Two
{
    [Export(typeof(IStudent))]
    [ExportMetadata("Type","TWO")]
    public class Two : IStudent
    {
        private string _Name;
        private int _Score;

        public Two()
        {
            _Name = "Bob";
            _Score = 90;
        }

        public string GetName()
        {
            return _Name;
        }

        public int GetScore()
        {
            return _Score;
        }
    }
}

 

□ StudentMEF.Client控制台程序

→ 需引用StudentMEF.Lib组件
→ 需引用System.ComponentModel.Composition组件
→ 需在可执行程序所在目录,即生成路径下,创建Extensions文件夹

 

需要一个帮助类StudentFactory,他的职责包括:

1、为了动态加载Extensions文件夹的所有扩展组件,可以使用Lazy<>来动态实现延迟加载,即只有当客户端程序使用到Extensions文件夹中组件的时候,再去加载这些扩展组件。
2、把扩展组件放到Catalog中,在CompositionContainer构建Part等,这些常规操作,也都需要。
3、提供一个方法,根据元数据ExportMetadata来获取对应的组件。

 

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using StudentMEF.Lib;

namespace StudentMEF.Client
{
    public class StudentFactory
    {
        [ImportMany]
        private Lazy<IStudent, IDictionary<string, object>>[] Students { get; set; }

        public StudentFactory()
        {
            var catalog = new AggregateCatalog();
            catalog.Catalogs.Add(new DirectoryCatalog(@".\Extensions"));
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

        public List<IStudent> GetStudents(string c)
        {
            List<IStudent> result = new List<IStudent>();
            foreach (var student in Students)
            {
                if ((string)student.Metadata["Type"] == c)
                {
                    result.Add(student.Value);
                }
            }
            return result;
        }     
    }
}

Lazy<IStudent, IDictionary<string, object>>中,第二个参数IDictionary<string, object>与ExportMetadata("Type","TWO")对应。

        static void Main(string[] args)
        {
            string c = "";
            while (true)
            {
                Console.WriteLine("输入学生类型:");
                c = Console.ReadLine();
                StudentFactory studentFactory = new StudentFactory();
                List<IStudent> students = studentFactory.GetStudents(c.ToUpper());
                if (students.Count == 0)
                {
                    Console.WriteLine("没有此类型学生~");
                }
                else
                {
                    foreach (IStudent student in students)
                    {
                        Console.WriteLine(string.Format("姓名:{0},分数:{1}",student.GetName(),student.GetScore()));
                    }
                }
            }
            Console.ReadKey();
        }

 

当Extensions文件夹中只有StudentMEF.One.dll组件,输入one,找到匹配,输入two找不到匹配;不关闭控制台程序,把StudentMEF.Two.dll也放入 Extensions文件夹,再输入two,找到匹配。      

MEF(Managed Extensibility Framework)有选择性地使用扩展组件的更多相关文章

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

    MEF(Managed Extensibility Framework),所在命名空间是System.ComponentModel.Composition.dll.简单来说,MEF是将符合约定(一般是 ...

  2. MEF(Managed Extensibility Framework) 微软平台插件化开发

    体验Managed Extensibility Framework精妙的设计   MEF(Managed Extensibility Framework)是.NET Framework 4.0一个重要 ...

  3. MEF(Managed Extensibility Framework)依赖注入学习

    MSDN官方资料,并且微软还提供了SimpleCalculator sample学习样例 http://msdn.microsoft.com/en-us/library/dd460648(v=vs.1 ...

  4. MEF(Managed Extensibility Framework )的入门介绍

    1.什么是MEF MEF是一个来自于微软协作构建扩展应用的新框架,它的目的是在运行中的应用中添加插件.MEF继承于.NET 4.0 Framework平台,存在于各种应用平台的系统程序集中 2.程序集 ...

  5. 使用Managed Extensibility Framework方便的扩展应用程序

    概述 Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)以及Duck Typing等.MEF为开发 ...

  6. .Net中的插件框架Managed Extensibility Framework

    Managed Extensibility Framework(MEF)是微软的一个用来扩展.NET应用程序的框架,它最初为了满足Visual Studio里的编辑器的需求,比如说,延迟加载所有东西和 ...

  7. 体验Managed Extensibility Framework精妙的设计

    MEF(Managed Extensibility Framework)是.NET Framework 4.0一个重要的库,Visual Studio 2010 Code Editor的扩展支持也是基 ...

  8. 实战MEF(1)一种不错的扩展方式

    在过去,我们完成一套应用程序后,如果后面对其功能进行了扩展或修整,往往需要重新编译代码生成新的应用程序,然后再覆盖原来的程序.这样的扩展方式对于较小的或者不经常扩展和更新的应用程序来说是可以接受的,而 ...

  9. Extjs 5 可选择日期+时间的组件DateTimeField

    我们都知道ExtJs有日期组件DateField,但直到ExtJs 5.0版本该日期组件也只能选择日期,不能选择时间(具体到时.分.秒),而实际工作中又常常会有需要日期和时间同时选择的需求,我们只能自 ...

随机推荐

  1. inherited 的研究。

    结论: 1. inherited默认调用的是父类的同名 同参数方法.(常用,如果是同名 同参数方法 比如 overide 的,可以省略,只写个inherited就可.) 2. 子类的方法里可以 inh ...

  2. 使用jsplumb的一些笔记

    欢迎就是需要使用jsplumb跟正在使用jsplumb的一起讨论 欢迎私聊 1.关于jsplumb的connection的一些事件 ####connection拖动的事件 instance.bind( ...

  3. SQL中EXCEPT和Not in的区别?

    初始化两张表: CREATE TABLE tb1(ID int) INSERT tb1          SELECT NULLUNION  ALL          SELECT NULLUNION ...

  4. Zookeeper原理架构与搭建

    一.Zookeeper到底是什么!? 学一个东西,不搞明白他是什么东西,哪还有心情学啊!! 首先,Zookeeper是Apache的一个java项目,属于Hadoop系统,扮演管理员的角色. 然后看到 ...

  5. Java模拟按键

    JDK自带了Robot类,此类用于为测试自动化.自运行演示程序和其他需要控制鼠标和键盘的应用程序生成本机系统输入事件.Robot 的主要目的是便于 Java 平台实现自动测试. 详情可查看jdk1.6 ...

  6. PIPESTATUS 对于ksh 无效

    BASH SHELL中,通常使用 $? 来获取上一条命令的返回码. 对于管道中的命令,使用$?只能获取管道中最后一条命令的返回码,例如 下面的例子中/not/a/valid/filename是一个不存 ...

  7. C#中的特性 (Attribute) 入门 (一)

    C#中的特性 (Attribute) 入门 (一) 饮水思源 http://www.cnblogs.com/Wind-Eagle/archive/2008/12/10/1351746.html htt ...

  8. iOS 11开发教程(十)iOS11无线连接手机真机测试

    iOS 11开发教程(十)iOS11无线连接手机真机测试 在Xcode 9.0中,已经可以通过无线连接手机进行真机测试了.具体的操作步骤如下: (1)首先需要使用数据线将手机连接到苹果电脑上. (2) ...

  9. luoguP4101 [HEOI2014]人人尽说江南好 结论

    题目大意: 给定\(n\)堆初始大小为\(1\)的石堆 每次选择两堆石子合并,特别的,合并之后的两堆石子不能\(> m\) 询问先手必赢? 不妨设我们是先手,且最后我们必胜 我们考虑构造局面\( ...

  10. CF696B Puzzles 期望

    显然可以树形$dp$ 令$f[i]$表示$i$号节点的期望时间戳 不妨设$fa$有$k$个子节点,对于$i$的子节点$u$,它是第$j(1 \leqslant j \leqslant k)$个被访问的 ...