MEF(Managed Extensibility Framework)有选择性地使用扩展组件

在"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,找到匹配。

时间: 2024-10-08 23:36:39

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

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

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

MEF(Managed Extensibility Framework )的入门介绍

1.什么是MEF MEF是一个来自于微软协作构建扩展应用的新框架,它的目的是在运行中的应用中添加插件.MEF继承于.NET 4.0 Framework平台,存在于各种应用平台的系统程序集中 2.程序集 System.ComponentModel.Composition.dll 3.关键结构 Import Export Compose 4.相关知识 Part:一个对象,能导入或者导出与应用程序 Catalog:一个对象,帮助在程序集或者文件夹中查找有效的构建部件 Contract:导入和导出部分需

.Net4下的MEF(Managed Extensibility Framework) 架构简介

转载自 http://zhoujg.blog.51cto.com/1281471/519269 在上篇WPF -.Net 4.0解决了DataGrid分组时的内存泄露中说过由于内存泄露问题,OpenExpressApp升级到.Net4平台,然后升级后之前的compositewpf出了点问题.在OpenExpressApp考虑动态扩展组件机制方面,以前就考虑过MEF,但当时还不成熟,所以使用了compositewpf,而现在MEF已经成为了.Net第一公民,compositewpf又没有提供.Ne

MEF(Managed Extensibility FrameWork) API

作用:创建可扩展的轻量级应用程序的库.可以让扩展在程序内重复使用,还可以跨程序重复使用. 导出Export:把部件放到容器中,供其它部件使用. 导入Import:把部件从容器中拿出来使用. 导入和导出必须具有相同的约定:协定类型参数   &&  协定名称参数 隐式协定:协定类型参数和协定名称参数将从修饰的属性推断而出. 导出的类型必须与协定类型相同.派生自协定类型,或者实现协定类型接口. public class MyClass { [Import] public IMyAddin MyA

Managed Extensibility Framework (MEF)

http://msdn.microsoft.com/zh-cn/library/dd460648(v=vs.110).aspx [.NET] 浅谈可扩展性框架:MEF

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

我们都知道ExtJs有日期组件DateField,但直到ExtJs 5.0版本该日期组件也只能选择日期,不能选择时间(具体到时.分.秒),而实际工作中又常常会有需要日期和时间同时选择的需求,我们只能自己扩展了,网上也有一些扩展好的现成组件,要么是早期版本的,ExtJs5.0版本的无法用,要么就是测试不充分,代码拿过来也用不了.于是笔者就只能自己动手了.先来看一下完成后的效果图: 先说一下思路: 我们需要如上图这样的组件,首先我们得有一个能够设置时.分.秒的组件,我们取名TimePickerFie

选择性地序列化方式

why选择性序列化? 实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字.换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化. 总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要

VMSS上用Managed Disk和Data Disk进行自动扩展(2)

10. 到目前为止,基本的模板配置已经完成,接下来我们使用Azure CLI 2.0来创建虚拟机自动扩展集合: az group create --name linuxvmssmanaged --location 'China North' az group deployment create --name mylinuxdeployment --resource-group linuxvmssmanaged --template-file vmsslinuxmanaged.json --par

VMSS上用Managed Disk和Data Disk进行自动扩展(1)

虚拟机自动扩展集(VMSS)是Azure上一个非常强大的功能,在我之前的系列文档中已经做了详细的介绍,在此就不赘述了:我同时也提到,在使用Azure传统存储账号的时候,也存在诸多限制,比如你需要计算每个存储账号下虚拟机的数量以避免IOPS超过性能限制,需要考虑扩展集中虚拟机数量限制,自定义镜像的限制等等: 在用户进行大规模扩展的设计和使用中,使用传统存储账号非常不方便,所以我们在生产环境下,推荐用户使用在中国区新上线的托管磁盘(managed disk).托管磁盘是将虚拟机的磁盘管理集中交给后台