當使用子容器的時候,基於特定的標準(Specific Criteria)過濾目錄是很必要的。好比,基於部件構造策略的過濾器是很常見的。下面的代碼片斷演示瞭如何構建的特殊途徑(Particular Approach):web
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();
[PartMetadata("scope", "webrequest"), Export] public class HomeController : Controller { }
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();
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; } } }