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. Cracking the coding interview--问题与解答

    http://www.hawstein.com/posts/ctci-solutions-contents.html 作者:Hawstein出处:http://hawstein.com/posts/c ...

  2. Android该HTTP下载

    今天学习了Android开发中比較难的一个环节,就是断点续传下载,非常多人看到这个标题就感觉头大.的确,假设没有良好的逻辑思维,这块的确非常难搞明确.以下我就将自己学到的知识和一些见解写下供那些在这个 ...

  3. WPF-21:WPF实现仿安卓的图案密码键盘(初级)

    希望大家有这方面好的代码给提供下,谢谢了! 想用C#做一个和手机上一样的图形密码键盘,貌似这方面资料比较少,虽然winphone手机上也有但是网上也没有这方面的代码.只好用常规的思维去实现一下,当然是 ...

  4. Ubuntu Linux 永山(mount)分

    在一般情况下,我们想安装一个分区解决方案是使用mount命令,因为我想/dev/sda3安装/media/aborn/data通过使用下面的命令 sudo mount /dev/sda3 /media ...

  5. VS2010不能编译SQLServer2005的Microsoft.SQLServer.ManagedDTS.dll的解决方法

    VS2010不能编译SQLServer2005的Microsoft.SQLServer.ManagedDTS.dll是最近碰到的一个疑难杂症问题,通过查询微软社区和一些英文资料找到了解决方法,同事说之 ...

  6. 丢弃重口味的xml配置--spring4用groovy配置bean(转)

    spring4之前,bean的配置可以主要分为两种方式,一种是使用基于xml,个人非常讨厌这种方式,因为明明一件很简单的事,放在xml中就会多了不少繁杂的信息.另一种方式,是从spring3.0开始, ...

  7. Eclipse+Maven创建webapp项目<二> (转)

    Eclipse+Maven创建webapp项目<二> 1.开启eclipse,右键new——>other,如下图找到maven project 2.选择maven project,显 ...

  8. 【安卓笔记】高速的发展设置界面-----PreferenceActivity

    通常app都会有一个设置界面,例如以下: 通常做法是自定义布局,然后在代码里面加入响应函数,并将结果保存到Sharedpreferences中. android给我们提供了PreferenceActi ...

  9. tokumx经营报表

    #见数据库列表  show dbs #切换/创建数据库(当创建一个集合(table)的时候会自己主动创建当前数据库) use admin; #添加用户  db.addUser("zhoulf ...

  10. 【Java先进】Lock、通过使用线程池

    import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util ...