MEF初体验之八:过滤目录
2014-04-14 22:14
183 查看
当在使用子容器的时候,基于某些具体标准来过滤目录可能是重要的。例如,基于部件的创建策略来过滤是很常见的。下面的代码片段演示了如何构建这种特别方法:
如果CreationPolicy还足以作为一个标准来选择部件的话,你或许想使用[PartMetadata]来代替。它允许你附加元数据在部件上,因此你可以使用它来构建一个过滤表达式。例如,下面是一个应用该特性的类:
这使你可以用那些应该被限定到一个(逻辑)web请求的部件来创建子容器。注意它由你来定义一个范围边界,换句话说,MEF并不知道"webrequest"是什么,因此,你必须在每次web请求时建立一些基础设施代码来创建/释放容器。
注意:我们没有提供FilteredCatalog类。下面我们将拿一个简单的实现来说明创建FilteredCatalog:
最后举个简单例子:
输出如图:
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 编程指南(八):过滤目录
- Java实现将目录下指定类型文件全部删除_FileFilter文件过滤
- 利用 python 对目录下的文件进行过滤删除
- [MEF]第04篇 MEF的多部件导入(ImportMany)和目录服务
- [MEF]第05篇 MEF的目录(Catalog)筛选
- MEF程序设计指南六:MEF中的目录服务(DeploymentCatalog)
- python递归解析、过滤目录、保留某个目录中的一系列子目录
- Python中实现从目录中过滤出指定文件类型的文件
- MEF 编程指南(七):使用目录
- shell脚本 过滤出对应目录下的所有png文件名
- winscp上传过滤目录和文件
- MEF应用(4) 组合容器 目录
- MEF程序设计指南七:使用目录(Catalog)动态装载xap与目录筛选(Filtered Catalog)
- 文件过滤驱动--隐藏目录
- FilenameFilter 文件过滤器--指定目录过滤后缀名
- 过滤当前目录下的一级目录(不包含目录下的目录)
- 过滤驱动实现目录重定向之(完整版本程序下载以及使用)
- 文件目录Java之文件实用操作(过滤、树形显示、排序)
- MEF初体验之十:部件重组
- 我学MEF系列目录