MEF(Managed Extensibility FrameWork) API

作用:创建可扩展的轻量级应用程序的库。可以让扩展在程序内重复使用,还可以跨程序重复使用。

导出Export:把部件放到容器中,供其它部件使用。

导入Import:把部件从容器中拿出来使用。

导入和导出必须具有相同的约定:协定类型参数   &&  协定名称参数

隐式协定:协定类型参数和协定名称参数将从修饰的属性推断而出。

导出的类型必须与协定类型相同、派生自协定类型,或者实现协定类型接口。

public class MyClass
{
    [Import]
    public IMyAddin MyAddin { get; set; }
}

协定类型:IMyAddin

协定名称:依据该协定类型创建的唯一字符串。

[Export(typeof(IMyAddin))]
public class MyLogger : IMyAddin { }

协定类型:IMyAddin

协定名称:从协定类型推断而出的。

[Export]
public class MyLogger : IMyAddin { }

协定类型:MyLogger

public class MyClass
{
    [Import("MajorRevision")]
    public int MajorRevision { get; set; }
}

public class MyExportClass
{
    [Export("MajorRevision")] //This one will match.
    public int MajorRevision = 4;

    [Export("MinorRevision")]
    public int MinorRevision = 16;
}

MyClass :

协定类型:MajorRevision

协定名称:MajorRevision

导入和导出方法

public class MyClass
{
    [Import] //Contract name must match!
    public Func<int, string> DoSomething { get; set; }
}
public class MyAddin
{
    //Explicitly specifying a generic type.
    [Export(typeof(Func<int, string>))]
    public string DoSomething(int TheParam);
}

动态导入:

在某些情况下,导入类可能需要与具有特定协定名称的多个导出匹配。

public class MyClass
{
    [Import("TheString")]
    public dynamic MyAddin { get; set; }
}
[Export("TheString", typeof(IMyAddin))]
public class MyLogger : IMyAddin { }

[Export("TheString")]
public class MyToolbar { }

延迟导入:Lazy<>

在某些情况下,导入类可能需要间接引入导入的对象,因此不会立即实例化该对象。

public class MyClass
{
    [Import]
    public Lazy<IMyAddin> MyAddin { get; set; }
}
[Export(typeof(IMyAddin))]
public class MyLogger : IMyAddin { }

必备导入:ImportingConstructor

导出的MEF部件通常由组合引擎创建,以响应填写匹配的导入的直接请求或需求。

public class MyClass
{
    private IMyAddin _theAddin;

    //Parameterless constructor will NOT be
    //used because the ImportingConstructor
    //attribute is present.
    public MyClass() { }

    //This constructor will be used.
    //An import with contract type IMyAddin is
    //declared automatically.
    [ImportingConstructor]
    public MyClass(IMyAddin MyAddin)
    {
        _theAddin = MyAddin;
    }
}

ImportingConstructor特性为所有参数导入使用推断出的协定类型和协定名称。可以用Import特性修饰参数重写此行为。

[ImportingConstructor]
public MyClass([Import(typeof(IMySubAddin))]IMyAddin MyAddin)
{
    _theAddin = MyAddin;
}

可选导入:AllowDefault

Import 特性指定部件正常运行的要求。如果导入无法得到满足,则该部件的组合将失败,并且部件将不可用。

public class MyClass
{
    [Import(AllowDefault = true)]
    public Plugin thePlugin { get; set; }

    //If no matching export is available,
    //thePlugin will be set to null.
}

导入多个对象:ImportMany

导入同一协定匹配的多个导出。

public class MyClass
{
    [ImportMany]
    public IEnumerable<Lazy<IMyAddin>> MyAddin { get; set; }
}

避免发现:PartNotDiscoverable

创建策略

共享:只有在部件尚不存在时才会实例化新的副本,否则它将提供现有副本。

非共享: 每次导入实例化的新副本。适用于每个导入需要其自己内部状态的部件。

[Export]     //未指定创建策略(默认Any)
public class PartOne
{
    //The default creation policy for an export is Any.
}

public class PartTwo     //
{
    [Import]    //未指定创建策略(默认Any)
    public PartOne partOne { get; set; }    //导入和导出均(Any),因此共享PartOne

}

public class PartThree
{
    [Import(RequiredCreationPolicy = CreationPolicy.Shared)]      //指定Shared创建策略
    public PartOne partOne { get; set; }    //和PartTow共享PartOne副本
}

[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]     //指定NonShared创建策略
public class PartFour
{

}

public class PartFive
{
    [Import]
    public PartFour partFour { get; set; }     //非共享
}

public class PartSix
{
    [Import(RequiredCreationPolicy = CreationPolicy.NonShared)]   //指定NonShared创建策略
    public PartFour partFour { get; set; }    //收到各自PartFour的独立副本
}

public class PartSeven
{
    [Import(RequiredCreationPolicy = CreationPolicy.Shared)]     //指定Shared创建策略
    public PartFour partFour { get; set; }   //没有创建策略为PartFour的已导出Shared,因此没人匹配
}

PartOne 未指定创建策略,因此默认值为 AnyPartTwo 未指定创建策略,因此默认值为 Any。 由于导入和导出均默认为 Any,因此将共享 PartOnePartThree 指定 Shared 创建策略,因此 PartTwoPartThree 将共享 PartOne的同一副本。 PartFour 指定 NonShared 创建策略,因此 PartFourPartFive中将为非共享。 PartSix 指定一个 NonShared 创建策略。 PartFivePartSix 将各自收到 PartFour的单独副本。 PartSeven 指定一个 Shared 创建策略。 由于没有创建策略为 PartFour 的已导出 Shared,因此 PartSeven 导入不与任何内容匹配,并且将不会得到满足。

生命周期和释放:IDisposable 和 IPartImportSatisfiedNotification

"非共享":ReleaseExport()

原文地址:https://www.cnblogs.com/ljdong7/p/12587741.html

时间: 2024-07-30 16:52:35

MEF(Managed Extensibility FrameWork) API的相关文章

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:导入和导出部分需

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

在"MEF(Managed Extensibility Framework)使用全部扩展组件"中,客户端应用程序调用了所有的扩展组件,而且如果有新的扩展组件加入,必须先关闭程序,再重新启动才可以调用所有组件. 本篇体验使用MEF的ExportMetadata特性,有选择性地使用某些扩展组件,使用Lazy<>,让客户端程序延迟动态加载组件,即使不关闭应用程序,也能调用所有组件. ● StudentMEF.Lib, 类库,包含接口IStudent.cs ● StudentMEF

.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

Managed Extensibility Framework (MEF)

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

Microsoft Win32 to Microsoft .NET Framework API Map

Microsoft Win32 to Microsoft .NET Framework API Map .NET Development (General) Technical Articles Microsoft .NET Framework and Microsoft Visual Studio User Education TeamsMicrosoft Corporation January 2004 Applies to:    Microsoft® .NET Framework ver

Django REST Framework API Guide 03

本节大纲 1.Routers 2.Parsers 3.Renderers Routers Usage from rest_framework import routers router = routers.SimpleRouter() router.register(r'users', UserViewSet) router.register(r'accounts', AccountViewSet) urlpatterns = router.urls register的两个必填参数prefix,

06-REST Framework - API

# Django REST Framework# 1. REST- 前后端分离- API-ApplicationProgrammingInterface - 为了应付千变万化的前端需求- REST:RepresataionsStateTrans - 20000 Fieding博士提出 - RESTful:遵守REST规范的技术设计的软件可以称为RESTful- REST规范 - URL代表一个资源,一个资源应该是一个名词 - 动作有HTTP的methode方法提供 - URL应该包含版本信息,版

Django REST framework API开发

RESTful设计方法 1. 域名 应该尽量将API部署在专用域名之下. https://api.example.com 如果确定API很简单,不会有进一步扩展,可以考虑放在主域名下. https://example.org/api/ 2. 版本(Versioning) 应该将API的版本号放入URL. http://www.example.com/app/1.0/foo http://www.example.com/app/1.1/foo http://www.example.com/app/