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

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还足以作为一个标准来选择部件的话,你或许想使用[PartMetadata]来代替。它允许你附加元数据在部件上,因此你可以使用它来构建一个过滤表达式。例如,下面是一个应用该特性的类:

[PartMetadata("scope", "webrequest"), Export]
public class HomeController : Controller
{
}

这使你可以用那些应该被限定到一个(逻辑)web请求的部件来创建子容器。注意它由你来定义一个范围边界,换句话说,MEF并不知道"webrequest"是什么,因此,你必须在每次web请求时建立一些基础设施代码来创建/释放容器。

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类。下面我们将拿一个简单的实现来说明创建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;
}
}
}

最后举个简单例子:

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 FilteringCatalogsSample
{
class Program
{
[ImportMany]
public IEnumerable<IMessageSender> Senders { get; set; }
static void Main(string[] args)
{
Program p = new Program();
p.Compose();
foreach (var item in p.Senders)
{
item.Send("Hi,MEF");
}
Console.ReadKey();
}
void Compose()
{
var catalog = new AssemblyCatalog(typeof(Program).Assembly);
var parent = new CompositionContainer(catalog);
var filterCatalog = new FilteredCatalog(catalog,
def => def.Metadata.ContainsKey("methods")
&& def.Metadata["methods"].ToString() == "sms");
//var AggrContainer = new CompositionContainer(filterCatalog, parent);
var child = new CompositionContainer(filterCatalog);
child.ComposeParts(this);
}
}
interface IMessageSender
{
void Send(string msg);
}
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Email sent:" + msg);
}
}
[Export(typeof(IMessageSender))]
public class SecureEmailSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("Secure Email sent:" + msg);
}
}
[Export(typeof(IMessageSender))]
[PartMetadata("methods","sms")]
public class SMSSender : IMessageSender
{
public void Send(string msg)
{
Console.WriteLine("SMS sent:" + msg);
}
}
}

输出如图:

MEF初体验之八:过滤目录的更多相关文章

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

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

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

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

  3. MEF初体验之七:Using Catalogs

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

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

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

  5. MEF初体验之五:Lazy Exports

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

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

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

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

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

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

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

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

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

随机推荐

  1. Gradle 修改 Maven 仓库地址(转)

    近来迁移了一些项目到Android Studio,采用Gradle构建确实比原来的Ant方便许多.但是编译时下载依赖的网速又着实令人蛋疼不已. 如果能切换到国内的Maven镜像仓库,如开源中国的Mav ...

  2. SWT实践过程中遇到的问题

    1.import org.eclipse.swt.widgets.Text; 诸如右所示的找不到这个包. 解决办法:project->properties->build path-> ...

  3. 在Xshell中上传下载文件到本地(linux中从多次ssh登录的dbserver里面的文件夹)

    在Xshell中上传下载文件到本地(linux中从多次ssh登录的dbserver里面的文件夹) 1 列出所有需要copy的sh文件 -bash-4.1$ ll /mysqllog/osw/*.sh ...

  4. 在TextView中加入图片

    TextView是一个非常强大的控件,有时须要在一个控件中同一时候显示图片和文字,使用TextView非常easy实现. 方法一: 聊天软件比方QQ一般都会有发送表情的功能,使用SpannableSt ...

  5. cf 323A A. Black-and-White Cube 立体构造

    A. Black-and-White Cube time limit per test 1 second memory limit per test 256 megabytes input stand ...

  6. 【ECSHOP插件】商品颜色尺寸仿淘宝选择功能免费发布

    先放效果图,如此实用的功能是不是迫不及待的要添加到自己的网店中了呢   牵涉到的修改文件(default模板为例) /themes/default/style.css /themes/default/ ...

  7. UI僵死分析

    原因剖析 UI僵死无非只是因为UI线程因繁忙而无法去接受用户的响应.详细说来内在原因有以下两个: 正常的业务代码写在UI线程中执行,业务代码的任务繁重导致UI线程无法分身去接受用户的界面输入 UI控件 ...

  8. android LinearLayout等view如何获取button效果

    我们可以给LinearLayout以及一切继承自View的控件,设置View.onClickListener监听,例如LInearLayout. 但是我们发现LinearLayout可以执行监听方法体 ...

  9. 苹果公司的新的编程语言 Swift 高级语言(十一)--初始化类的析构函数的一个实例

    一 .实例的初始化          实例的初始化是准备一个类.结构或枚举的实例以便使用的过程. 初始化包含设置一个实例的每个存储属性为一个初始值,以及运行不论什么其他新的实例可以使用之前须要的设置或 ...

  10. 为什么android你用的越多,速度较慢的手机

    依据第三方的调研数据显示,有 77% 的 Android 手机用户承认自己曾遭遇过手机变慢的影响,百度搜索"Android+ 卡慢",也有超过 460 万条结果. 在业内.Andr ...