MEF和CompositionContainer学习

最近在研究项目平台启动,发现使用的是CompositionContainer,就对其起了兴趣,初步研究了一下,发现时MS提供的扩展性框架 MEF,下面是本人的一点心得和大家共同探讨。

MEF定义:

Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)等。MEF为开发人员提供了一个工具,让我们可以轻松的对应用
程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后扩展人员就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序
之间不产生直接的依赖,这样也允许在多个具有同样的扩展需求之间共享扩展程序。

MEF组件,以Part形式,同事有Import和Export功能。

MEF导入导出:导入导出的类都继承同一个接口,然后把类实例化,最后在总的容器里导入。

接下来用代码实战了:

1:首先定义一个Metadata,可以附加自身附件信息。
元数据可用于将导出的对象的属性传递到导入部件。 导入部件可以使用此数据来决定要使用哪些导出,或收集有关导出的信息而不必构造导出。元数据视图接口必须只有属性,并且这些属性
必须具有 get 访问器。

public interface IPartInformation
    {
        string Name { get; }

        string Version { get; }

        Type PartType { get; }

        [DefaultValue(null)]
        Type[] Dependencies { get; }

        string Author { get; }

        string Contact { get; }

        string Date { get; }

        string Description { get; }

        string Comment { get; }
    }

2:定义一个公共接口,供导入导出继承

public interface ISinglePart
    {
    }

3:增加一个Class Library继承ISinglePart,同时标注Metadata和Export标签

    [Export(typeof(ISinglePart))]
    [ExportMetadata("Name","123")]
    [ExportMetadata("PartType", typeof(Class1))]
    [ExportMetadata("Author", "123")]
    [ExportMetadata("Contact", "123")]
    [ExportMetadata("Version", "2.0.0.0")]
    [ExportMetadata("Date", "2013/03/28")]
    [ExportMetadata("Description", "1234")]
    [ExportMetadata("Comment", "12345")]
    public class Class1:ISinglePart
    {
    }

4:增加MEF发现部件的方式:使用AssemblyCatalog 在当前程序集发现部件。

public class RecursiveDirectoryCatalog:ComposablePartCatalog
    {
        private AggregateCatalog _innerCatalog = null;

        public RecursiveDirectoryCatalog(string basePath, params string[] dirPaths)
        {
            var fullDirPaths = from p in dirPaths
                               let d = Path.IsPathRooted(p) ? p : Path.Combine(basePath, p)
                               select d;

            var asmCatalogs = from p in fullDirPaths
                              from dll in Directory.GetFiles(p, "*.dll", SearchOption.AllDirectories)
                              let cb = new AssemblyName().CodeBase = dll
                              where AssemblyHelp.IsManageDll(dll)
                              select new AssemblyCatalog(cb);

            _innerCatalog = new AggregateCatalog(asmCatalogs.OfType<ComposablePartCatalog>());
        }

        public override IQueryable<ComposablePartDefinition> Parts
        {
            get { return _innerCatalog.Parts; }
        }

        
    }

5:组合部件
在加载完部件之后,要把它们放到一个CompositionContainer容器中。

var catalog = new RecursiveDirectoryCatalog(basePath, partDirectories);
this.Container = new CompositionContainer(catalog);

6:导入程序负责指定将使用的元数据视图(如果有)。 包含元数据的导入将声明为延迟导入,其元数据接口作为 Lazy<T,T> 的第二个类型参数。 下面的类导入前面的部件以及元数据。

创建策略
当部件指定执行导入和组合时,组合容器将尝试查找匹配的导出。 如果它将导入与导出成功匹配,则导入成员将设置为导出的对象的实例。 导出部件的创建策略控制此实例来源于何处。导
入和导出都可从值 Shared、NonShared 或 Any 中指定部件的创建策略。 导入和导出的默认值均为 Any。

[ImportMany(RequiredCreationPolicy = CreationPolicy.Shared)]
public IEnumerable<Lazy<TSingle, IPartInformation>> SingleParts { get; private set; }

7:将指定部分加入CompositionBatch物件中,在容器上执行组合,包括指定的 CompositionBatch 中的更改,这样就能把Class1以及其Metadata导入至SingleParts中

var batch = new CompositionBatch();
batch.AddExportedValue(owner);
batch.AddExportedValue(this.Container);
batch.AddPart(this);

8:关于生命周期和释放

由于部件承载于组合容器中,因此其生命周期可能比普通对象更复杂,所以将只有拥有部件的容器才应对其调用 Dispose 方法。 容器本身实现 IDisposable,并且作为 Dispose 中其清理的
一部分,它将对拥有的所有部件调用 Dispose。

 public partial class AstPartContainer<TOwner, TSingle, TMultiple> : IDisposable
        where TOwner : class
        where TSingle : class
        where TMultiple : class
    {
    }

最后总结一下使用MEF,到底有什么用处?
假设项目中包含有大量的小组件,并且每一个组件都是都不同的开发小组开发的,甚至都无法提供源码,这样您就无法在不修改大量源码的情况下添加新的组件,但是如果使用MEF,对于同一
类型的组件继承同一个接口,定义导入导出,这样只需要提供相关DLL,就能以Part的形式加入容器中,供开发人员调用。其具有很强灵活性的可扩展支持

转载于:https://www.cnblogs.com/gavinhuang/archive/2013/03/29/2988459.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值