MEF 编程指南(八):过滤目录

当使用子容器的时候,基于特定的标准(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;

        }

    }

}
 
原文地址:

你可能感兴趣的:(编程)