MEF特性化编程模型的价值主张之一是通过catalogs动态发现部件的能力。Catalogs允许应用程序很容易地消费那些通过[Export]已经自我注册的exports。

Assembly Catalog

为了在一个特定的程序集中发现所有的exports,可以使用System.ComponentModel.Composition.Hosting.AssemblyCatalog类。

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

Directory Catalog

为了在一个目录中所有程序集中发现所有的exports,可以使用System.ComponentModel.Composition.Hosting.DirectoryCatalog类。

var catalog = new DirectoryCatalog("Extensions");

如果使用的是一个相对的目录,它将相对于当前AppDomain的基本目录。

DirectoryCatalog将扫描这个目录一次,当这个目录发生变化时,它将并不会自动刷新。然而,你可以实现你自己的扫描机制,在catalog上调用Refresh()方法使它重新扫描。一旦它重新扫描,将发生重组。

var catalog = new DirectoryCatalog("Extensions");
//some scanning logic
catalog.Refresh();

注意:在sliverlight中不支持DirectoryCatalog。

Aggregate Catalog

当AssemblyCatalog and DirectoryCatalog单独不充足,需要结合的catalogs时,应用程序可以使用System.ComponentModel.Composition.Hosting.AggregateCatalog类。一个AggregateCatalog将多个catalogs组合到一个单一的catalog中。通用的模式是添加当前执行的程序集和第三方扩展的一个directory catalog。你可以将要组合的catalog作为AggregateCatalog构造器参数或者使用AggregateCatalog的Catalogs属性来直接添加。

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

Type Catalog

为了在一系列指定的类型中发现所有的导出,将可以使用System.ComponentModel.Composition.Hosting.TypeCatalog类。

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

DeploymentCatalog - Sliverlight only

在Sliverlight中,MEF包含DeploymentCatalog,用来动态下载远程XAPs。有关更多DeploymentCatalog内容请查看DeploymentCatalog

Using catalog with a Container

为了使用catalog和container,只需简单地将catalog传到container的构造器即可。

var container = new CompositionContainer(catalog);

最后举个例子:

首先,在CommonLib类库中定义了一个接口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CommonLib
{
public interface ILogger
{
void Log(string msg);
}
}

然后,创建CatalogLib类库,引用CommonLib类库,并在里面定义一个ILogger类型契约的exports:

using CommonLib;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace CatalogLib
{
[Export(typeof(ILogger))]
public class FileLogger:ILogger
{
public void Log(string msg)
{
Console.WriteLine("File Logger:"+msg);
}
}
}

最后,创建CatalogsSample控制台程序,将CatalogLib的生成路径也改为该生成路径,并引用CommonLib,也创建一个ILogger类型契约的exports,在入口处组合,代码如下:

using CommonLib;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace CatalogsSample
{
class Program
{
[ImportMany]
public IEnumerable<ILogger> Loggers { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.Compose();
foreach (var item in p.Loggers)
{
item.Log("Hi,MEF");
}
Console.ReadKey();
}
void Compose()
{
var catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()), new DirectoryCatalog("."));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
}
[Export(typeof(ILogger))]
class DBLogger : ILogger
{
public void Log(string msg)
{
Console.WriteLine("DB Logger:" + msg);
}
}
}

输出如图:

MEF初体验之七:Using Catalogs的更多相关文章

  1. MEF初体验之二:定义组合部件和契约

    组合部件 在MEF中,一个组合部件就是一个组合单元,组合部件"出口"其它组合部件需要的服务并且从其它部件"进口"需要的服务.在MEF编程模型中,为了声明组合部件 ...

  2. MEF初体验之十:部件重组

    一些应用程序被设计成在运行时可以动态改变.例如,一个新的扩展被下载,或者因为其它的多种多样的原因其它的扩展变得不可用.MEF处理这些多样的场景是依赖我们称作重组的功能来实现的,它可已在最初的组合后改变 ...

  3. MEF初体验之一:在应用程序宿主MEF

    在MEF出现以前,其实微软已经发布了一个类似的框架,叫MAF(Managed Add-in Framework),它旨在使应用程序孤立和更好的管理扩展,而MEF更关心的是可发现性.扩展性和轻便性,后者 ...

  4. MEF初体验之十二:Composition Batch

    一个MEF容器实例是不可变的.如果catalog支持改变(像观察一个目录的改变)或是如果你的代码在运行时添加或移除部件,改变都可能发生.以前,你不得不作出改变并在组合容器上调用它的组合方法.在Prev ...

  5. MEF初体验之九:部件生命周期

    理解MEF容器中部件的生命周期及其含义是非常重要的.鉴于MEF重点在开放端应用程序,这将变得尤其重要的,一旦app ships和第三方扩展开始运行,作为应用程序的开发者将很好地控制这一系列的部件.生命 ...

  6. MEF初体验之八:过滤目录

    当在使用子容器的时候,基于某些具体标准来过滤目录可能是重要的.例如,基于部件的创建策略来过滤是很常见的.下面的代码片段演示了如何构建这种特别方法: var catalog = new Assembly ...

  7. MEF初体验之五:Lazy Exports

    在一个部件组合中,导入将触发一个部件或者多个部件的实例化,这些部件暴露了所需原请求部件的必要的导入.对于一些应用程序来说,延迟实例化-防止图结构下的递归组合-可能对于将创建一个长久复杂的开销很大而不必 ...

  8. MEF初体验之四:Imports声明

    组合部件使用[System.ComponentModel.Composition.ImportAttribute]特性声明导入.与导出类似,也有几种成员支持,即为字段.属性和构造器参数.同样,我们也来 ...

  9. MEF初体验之三:Exports声明

    组合部件通过[ExportAttribute]声明exports.在MEF中,有这么几种成员可声明exports的方式:组合部件(类).字段.属性和方法.我们来看下ExportAttribute类的声 ...

随机推荐

  1. WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心

    原文:WPF界面设计技巧(11)-认知流文档 & 小议WPF的野心 流文档是WPF中的一种独特的文档承载格式,它的书写和呈现方式都很像HTML,它也几乎具备了HTML的绝大多数优势,并提供了更 ...

  2. 后台使用oracle前台使用easyui分页机制

    前台easyui 的datagrid中设置分页属性: pagination:true,//显示分页 pagePosition:'bottom',//分页栏位置 both 上下 bottom.top p ...

  3. Extjs4.10Model模型具体解释

    一.创建Model模型 Extjs4.10提供了两种方法来创建Model模型,也就是创建类 方法一: Ext.define('person',{              extend:'Ext.da ...

  4. MYSQL正在使用select发现现场记录方法,包括一个逗号分隔的字符串

    首先,我们创建一个逗号分隔字符串. CREATE TABLE test(id int(6) NOT NULL AUTO_INCREMENT,PRIMARY KEY (id),pname VARCHAR ...

  5. pygame系列_箭刺Elephant游戏

    这个游戏原名为:Chimp,我们可以到: http://www.pygame.org/docs/tut/chimp/ChimpLineByLine.html 获取到源码和详细的源码讲解 下面是我对游戏 ...

  6. CF 439D(251D题)Devu and his Brother

    Devu and his Brother time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. Unable to start MySQL service. Another MySQL daemon is already running with the same UNIX socket

    Unable to start MySQL service. Another MySQL daemon is already running with the same UNIX socket 特征 ...

  8. SICP 1.20经验

    1.20 两者之间的主要区别是,使我们明白的操作顺序. 网上找一些答案,都死了扩大. 我们所从事的IT的. 展开搞死人IT实践. 首先考虑应用程序 我们得到 gcd(206, 40) -> gc ...

  9. Ext4功能和文件系统的简单功能

    Linux kernel 自 2.6.28 開始正式支持新的文件系统 Ext4. Ext4 是 Ext3 的改进版,改动了 Ext3 中部分重要的数据结构,而不只像 Ext3 对 Ext2 那样,不过 ...

  10. xml和json选择奖

    xml&json战争,一般能够分离两个对立阵营.党的手感json足够强大以便能够替代xml.有一方感觉json滑稽丑陋,绝对没有和xml赛可能. 为了避免"拉仇恨"(我不是 ...