当使用子容器的时候,基于特定的标准(Specific Criteria)过滤目录是很必要的。比如,基于部件构造策略的过滤器是很常见的。下面的代码片段演示了如何构建的特殊途径(Particular Approach):

 
 var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var parent = new CompositionContainer(catalog); var filteredCat = new FilteredCatalog(catalog,
def => def.Metadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName) &&
((CreationPolicy)def.Metadata[CompositionConstants.PartCreationPolicyMetadataName]) == CreationPolicy.NonShared);
var child = new CompositionContainer(filteredCat, parent); var root = child.GetExportedObject<Root>();
child.Dispose();
 
如果 CreationPolicy 作为标准选择部件不能满足需求,你可能想到使用 [System.ComponentModel.Composition.PartMetadataAttribute] 替代。它允许为部件附加元数据,因此可以使用它构建过滤表达式。下面的示例就是 PartMetadata 特性的应用:
 
 [PartMetadata("scope", "webrequest"), Export]
public class HomeController : Controller
{
}  
 
这允许你创建局限于 Web 请求(逻辑)部件的子容器。请注意:范围边界取决于你的定义,换句话说,MEF 不知道 "webrequest"是什么,所以你不得不创建一些基础代码来在每次Web 请求时创建/回收(Create/Dispose)容器。
 
 var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var parent = new CompositionContainer(catalog); var filteredCat = new FilteredCatalog(catalog,
def => def.Metadata.ContainsKey("scope") &&
def.Metadata["scope"].ToString() == "webrequest");
var perRequest = new CompositionContainer(filteredCat, parent); var controller = perRequest.GetExportedObject<HomeController>();
perRequest.Dispose();
注意:我们并没有提供 FilteredCatalog 类。下面演示了如何构建一个简单的实现。
 
using System;
using System.ComponentModel.Composition.Primitives;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Linq.Expressions; public class FilteredCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
{
private readonly ComposablePartCatalog _inner;
private readonly INotifyComposablePartCatalogChanged _innerNotifyChange;
private readonly IQueryable<ComposablePartDefinition> _partsQuery; public FilteredCatalog(ComposablePartCatalog inner,
Expression<Func<ComposablePartDefinition, bool>> expression)
{
_inner = inner;
_innerNotifyChange = inner as INotifyComposablePartCatalogChanged;
_partsQuery = inner.Parts.Where(expression);
} public override IQueryable<ComposablePartDefinition> Parts
{
get
{
return _partsQuery;
}
} public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed
{
add
{
if (_innerNotifyChange != null)
_innerNotifyChange.Changed += value;
}
remove
{
if (_innerNotifyChange != null)
_innerNotifyChange.Changed -= value;
}
} public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing
{
add
{
if (_innerNotifyChange != null)
_innerNotifyChange.Changing += value;
}
remove
{
if (_innerNotifyChange != null)
_innerNotifyChange.Changing -= value;
}
}
}
 
原文地址:

MEF 编程指南(八):过滤目录的更多相关文章

  1. MEF 编程指南(九):部件生命周期

    理解 MEF 容器部件生命周期和实现是非常重要的事情.考虑到 MEF 关注可扩展应用程序.这变得尤为重要.生命期可以解释为期望部件的共享性(transitively, its exports)   共 ...

  2. MEF 编程指南(二):定义可组合部件和契约

    可组合部件(Composable Parts)   在 MEF 内部可组合部件是一个可组合单元.可组合部件导出其他可组合部件需要的服务,并且从其他可组合部件导入服务.在 MEF 编程模型中,可组合部件 ...

  3. MEF 编程指南(七):使用目录

    目录(Catalogs)   MEF 特性编程模型的核心价值,拥有通过目录动态地发现部件的能力.目录允许应用程序轻松地使用那些通过 Export Attribute 注册自身的导出.下面列出 MEF ...

  4. MEF 编程指南(十二):批量组合

    MEF 容器实例并非不可变的.如果目录支持改变(像监控目录变动)或者在运行时添加/移除部件都可能发生改变.以前,你不得不做出改动并且调用 CompositionContainer 上的 Compose ...

  5. MEF 编程指南(十):重组

    有些应用程序被设计成在运行时动态地改变.例如,一个新的扩展可能被下载,或者其他原因变得不可用.MEF 依靠我们称之为重组(Composition)的技术处理,在初始化组合以后改变导入值的场景.   导 ...

  6. MEF 编程指南(六):导出和元数据

    声明导出解释了部件导出服务的基础知识和价值观(Values).有时候出于种种原因,导出关联信息是非常必要的.通常,用于解释关于功能公共契约的具体实现.允许导入满足约束要求的导出,或者导入所有可用的实现 ...

  7. MEF 编程指南(一):在应用中托管 MEF

    在应用程序中托管(Hosing) MEF 涉及到创建组合容器(CompositionContainer) 实例,添加可组合部件(Composable Parts),包括应用程序宿主(Host)本身并进 ...

  8. MEF 编程指南(十一):查询 CompositionContainer

    CompositionContainer 公开了一部分获取导出.导出对象以及两者集合的重载.   在这些方法重载中,你应该遵循下面的共享行为准则 - 除非特别说明.   当请求单一实例的时候,如果没发 ...

  9. MEF 编程指南(五):延迟导出

    在组合部件的时候,导入将会触发部件(部件集合)的实例化,为原始的请求部件公开必要的导出需求.对于有些应用程序,推迟实例化 - 并且防止递归组合图(Recursive Composition Down ...

随机推荐

  1. 自己用的框架写了一个PHP模版解析类

    <?php if(!defined('IS_HEARTPHP')) exit('Access Denied'); /** * template.class.php 模板解析类 * * @copy ...

  2. Azure SQL 数据库:服务级别与性能问答

    ShawnBice    2014 年 5 月 5 日上午 10:00 几天前,我发表了一篇文章,并就 4 月 24 日发布的适用于Windows Azure SQL 数据库的新服务级别提供了一些预料 ...

  3. Android精美的日历控件

    网上看到的精美日历控件,谨以此文记录一下,用到的时候再来翻翻 源码地址 : http://download.csdn.net/detail/abc13939746593/7265459

  4. group by的使用

    1.概述 2.原始表 3.简单Group By 4.Group By 和 Order By 5.Group By中Select指定的字段限制 6.Group By All 7.Group By与聚合函 ...

  5. 延迟加载图片的 jQuery 插件——lazyload.js

    lazyload 这个 jQuery 插件,是用来缓冲加载图片的插件.如果一篇文章很长有很多图片的话,下载图片就需要很多时间.而这款插件,会检测你的滚动情况,只有你要看到那个图片的时 候,它才会从后台 ...

  6. Java Error和Exception区别

    Error和Exception都继承自Throwable: 二者不同之处: Exception: 1.可以是可被控制(checked)或者不可控制(unchecked): 2.表示一个由程序员导致的错 ...

  7. msssql 用numberic(38)替代int去解决int不够的问题

    发现ms sql server的问题int(-2^31 ~ 2 ^ 31 -1)与程序中的UINT有时会对不上的时候, 发现如果用numberic(32)来做判断好像解决, 暂时就现在的插入操作来看, ...

  8. String.valueOf()

    1. 由 基本数据型态转换成 String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 也就是 String.valueOf() 这个参数多载的方法 有下 ...

  9. IOS NSNotificationCenter 通知的使用

    1.注册通知 [NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notify) name:@" ...

  10. 用Vmware安装centos5

    Vmware安装过程就不详述了,这里从创建虚拟机开始记录. 选择创建虚拟机 下一步 选择稍后安装 选择安装的操作系统版本,需要说明的是,CentOs 5 就是RHEL 5 设置虚拟机名称及虚拟机位置 ...