zoukankan      html  css  js  c++  java
  • 我学MEF系列(4):组合容器(CompositionContainer)和目录(Catalog)

    前言

      通过之前的文章,我们已经了解了MEF中的导入(Import)和导出(Export)。在本系列的第一篇文章中我们知道MEF其实还包括另外两个核心内容:组合容器(CompositionContainer)和目录(Catalog)。

    组合容器

      Castle有容器,Unity有容器,同样作为一个能够提供扩展机制,能够支持依赖注入的框架肯定也有容器。MEF的组合模型的核心是组合容器,该容器包含所有可用的部件并执行组合操作 (即,将导入和导出配对) 。通常我们使用的组合容器是:CompositionContainer ,MEF还提供一个组合对象:CompositionBatch。

    目录

      前面我们有谈到组合容器中包含所有可用部件,并对这些组件执行组合操作,我们可能会问容器怎么发现这些部件呢?答案就是:目录(Catalog)。

      目录就是一个对象,通过它可从某些源发现可用部件。 MEF 提供了用于从提供的类型、程序集或目录发现部件的目录。 应用程序开发人员可以轻松地创建用于从其他源(如 Web 服务)发现部件的新目录。

      MEF中提供的目录对象主要有:Assembly Catalog(程序集目录),Directory Catalog,Aggregate Catalog,Type Catalog,和仅使用在Silverlight中得目录Deployment Catalog( Silverlight only),Filtered Catalog.

    1.Assembly Catalog

    可以在给定的Assembly 发现所有的导出部件,使用类型AssemblyCatalog

    var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());

    2.Directory Catalog

    它可以在给定的目录(路径,相对路径或绝对路径)中发现导出部件,使用类型DirectoryCatalog。如果你使用的是相对路径,则相对的是当前AppDoamin的基路径。DirectoryCatalog只会对给定目录进行一次性扫描,目录发生变化是容器不会主动刷新,如果需要刷新给定的目录需要调用方法:Refresh() ,当目录刷新时,容器也会重新组合部件。

    var catalog = new DirectoryCatalog("Extensions");
    catalog.Refresh();

    3.Aggregate Catalog

    聚集目录,有时候我们使用单一的Assembly Catalog和Directory Catalog并不能解决我们的需求,我们可能需要同时使用到他们,这时候我们便可使用Aggregate Catalog,我们可以将Assembly Catalog和Directory Catalog同时添加到目录中,这种添加可以通过构造函数实现,也可以通过目录集合的添加方法来实现:catalog.Catalogs.Add(...)。聚集目录使用类型AggregateCatalog

    var catalog = new AggregateCatalog(
    new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
    new DirectoryCatalog("Extensions"));

    4.Type Catalog

    通过Type Catalog我们可以发现指定类型中得导出部件。使用类型TypeCatalog

    var catalog = new TypeCatalog(typeof(type1), typeof(type2), ...);

    5.Deployment Catalog
    Deployment Catalog,这种类型的目录仅支持Silverlight在后面的文章中我们会专门讲到如何在silverlight中使用MEF。

    6.Filtered Catalog

    已过滤的目录,通过FilteredCatalog可以筛选出特定的目录,特别是,您可以请求所有可加载的插件都有一个指示级别的元数据属性。

     1 var catalog = new AssemblyCatalog(typeof(Program).Assembly);
    2 var parent = new CompositionContainer(catalog);
    3
    4 var filteredCat = new FilteredCatalog(catalog,
    5 def => def.Metadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName) &&
    6 ((CreationPolicy)def.Metadata[CompositionConstants.PartCreationPolicyMetadataName]) == CreationPolicy.NonShared);
    7 var child = new CompositionContainer(filteredCat, parent);
    8
    9 var root = child.GetExportedObject<Root>();
    10 child.Dispose();

    示例来源于CodePlex

    • 一个简单的例子

    在介绍了这么多的基本知识后,MEF的基本概念也介绍的差不多了,这里给出一个简单完整一点的例子,供大家参考。

    在应用程序中寄宿MEF:

    View Code
     1 class Program    
    2 {
    3 //导入,使用默认的ContractType和ContractName
    4 [Import]
    5 public ILog log
    6 {
    7 get;
    8 set;
    9 }
    10
    11 static void Main(string[] args)
    12 {
    13 Program pro = new Program();
    14 pro.Compose();
    15 pro.log.AddLog(new Exception("My First MEF"));
    16 Console.Read();
    17 }
    18
    19 //组合方法
    20 private void Compose()
    21 {
    22 //指定目录为当前执行的程序集
    23 var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
    24 //使用AssemblyCatalog创建组合容器
    25 var container = new CompositionContainer(catalog);
    26
    27 //调用组合部件方法
    28 container.ComposeParts(this);
    29 }
    30 }
    31 //定义日志接口
    32 public interface ILog
    33 {
    34 void AddLog(Exception ex);
    35 }
    36
    37 //导出部件,指定协定类型(ContractType)为ILog
    38 [Export(typeof(ILog))]
    39 public class MyLog : ILog
    40 {
    41 public void AddLog(Exception ex)
    42 {
    43 Console.WriteLine(ex.ToString());
    44 }
    45 }

    注:本文参考文章:http://mef.codeplex.com/wikipage?title=Using%20Catalogs&referringTitle=Guide

    作者:ps_zw
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    PHP 开发 APP 接口 --Redis篇
    PHP 开发 APP 接口--静态缓存篇
    PHP 开发 APP 接口 --JSON、XML结合篇
    PHP 开发 APP 接口 --JSION篇
    PHP 开发 APP 接口--XML篇
    程序员必须掌握的600个英语单词
    Memcache
    伪静态
    ob缓冲
    函数的使用顺序---TABLES,USING,CHANGING
  • 原文地址:https://www.cnblogs.com/pszw/p/2284124.html
Copyright © 2011-2022 走看看