Skip to content

Commit

Permalink
Rewritten FilteringCatalog so that it use InterceptingCatalog internally
Browse files Browse the repository at this point in the history
  • Loading branch information
pwlodek committed Nov 15, 2010
1 parent a094d34 commit f50b13a
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 42 deletions.
4 changes: 2 additions & 2 deletions src/MefContrib.Tests/Hosting/FactoryExportDefinitionTests.cs
Expand Up @@ -2,7 +2,7 @@
using MefContrib.Hosting;
using NUnit.Framework;

namespace MefContrib.Tests.Hosting
namespace MefContrib.Hosting.Tests
{
[TestFixture]
public class FactoryExportDefinitionTests
Expand Down Expand Up @@ -33,7 +33,7 @@ public void ContractTypeAndNullNameAreProperlySetTest()
var exportDefinition = new FactoryExportDefinition(typeof(IComponent), null, ep => null);
Assert.That(exportDefinition.ContractType, Is.EqualTo(typeof(IComponent)));
Assert.That(exportDefinition.RegistrationName, Is.Null);
Assert.That(exportDefinition.ContractName, Is.EqualTo("MefContrib.Tests.Hosting.FactoryExportDefinitionTests+IComponent"));
Assert.That(exportDefinition.ContractName, Is.EqualTo("MefContrib.Hosting.Tests.FactoryExportDefinitionTests+IComponent"));
}
}
}
3 changes: 1 addition & 2 deletions src/MefContrib.Tests/Hosting/FactoryExportProviderTests.cs
Expand Up @@ -2,10 +2,9 @@
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using MefContrib.Hosting;
using NUnit.Framework;

namespace MefContrib.Tests.Hosting
namespace MefContrib.Hosting.Tests
{
[TestFixture]
public class FactoryExportProviderTests
Expand Down
Expand Up @@ -2,10 +2,9 @@
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using MefContrib.Hosting.Filter;
using NUnit.Framework;

namespace MefContrib.Tests.Hosting
namespace MefContrib.Hosting.Filter.Tests
{
[TestFixture]
public class FilteringCatalogTests
Expand Down
2 changes: 1 addition & 1 deletion src/MefContrib.Tests/MefContrib.Tests.csproj
Expand Up @@ -102,7 +102,7 @@
<Compile Include="Hosting\Conventions\TypeScannerConfiguratorTests.cs" />
<Compile Include="Hosting\Conventions\TypeScannerTests.cs" />
<Compile Include="Hosting\FactoryExportDefinitionTests.cs" />
<Compile Include="Hosting\FilteringCatalogTests.cs" />
<Compile Include="Hosting\Filter\FilteringCatalogTests.cs" />
<Compile Include="Hosting\FactoryExportProviderTests.cs" />
<Compile Include="Hosting\Interception\CompositeValueInterceptorTests.cs" />
<Compile Include="Hosting\Interception\Configuration\InterceptionConfigurationTests.cs" />
Expand Down
57 changes: 22 additions & 35 deletions src/MefContrib/Hosting/Filter/FilteringCatalog.cs
@@ -1,37 +1,38 @@
namespace MefContrib.Hosting.Filter
{
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Linq.Expressions;
using MefContrib.Hosting.Interception;
using MefContrib.Hosting.Interception.Configuration;

/// <summary>
/// Represents a catalog which wraps any <see cref="ComposablePartCatalog"/> and
/// filters out <see cref="ComposablePartDefinition"/>s based on a given criteria.
/// </summary>
public class FilteringCatalog : ComposablePartCatalog, INotifyComposablePartCatalogChanged
{
private readonly INotifyComposablePartCatalogChanged innerNotifyChange;
private readonly IQueryable<ComposablePartDefinition> partsQuery;
private readonly InterceptingCatalog interceptingCatalog;

/// <summary>
/// Initializes a new instance of the <see cref="FilteringCatalog"/> class.
/// </summary>
/// <param name="inner">A <see cref="ComposablePartCatalog"/> whose parts
/// are to be filtered based on a given criteria.</param>
/// <param name="expression">An <see cref="Expression"/> which defines the filter query.</param>
public FilteringCatalog(ComposablePartCatalog inner,
Expression<Func<ComposablePartDefinition, bool>> expression)
/// <param name="filter">A filter query.</param>
public FilteringCatalog(ComposablePartCatalog inner, Func<ComposablePartDefinition, bool> filter)
{
if (inner == null)
throw new ArgumentNullException("inner");

if (expression == null)
throw new ArgumentNullException("expression");
if (filter == null)
throw new ArgumentNullException("filter");

this.innerNotifyChange = inner as INotifyComposablePartCatalogChanged;
this.partsQuery = inner.Parts.Where(expression);
var cfg = new InterceptionConfiguration()
.AddHandler(new FilteringExportHandler(filter));
this.interceptingCatalog = new InterceptingCatalog(inner, cfg);
}

/// <summary>
Expand All @@ -42,46 +43,32 @@ public class FilteringCatalog : ComposablePartCatalog, INotifyComposablePartCata
/// <param name="filter">An instance of the <see cref="IFilter"/> interface
/// to be used as a filter query.</param>
public FilteringCatalog(ComposablePartCatalog inner, IFilter filter)
: this(inner, p => filter.Filter(p))
: this(inner, filter.Filter)
{
}

public override IQueryable<ComposablePartDefinition> Parts
{
get
{
return this.partsQuery;
}
get { return this.interceptingCatalog.Parts; }
}

public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
{
return this.interceptingCatalog.GetExports(definition);
}

#region INotifyComposablePartCatalogChanged Implementation

public event EventHandler<ComposablePartCatalogChangeEventArgs> Changed
{
add
{
if (this.innerNotifyChange != null)
this.innerNotifyChange.Changed += value;
}
remove
{
if (this.innerNotifyChange != null)
this.innerNotifyChange.Changed -= value;
}
add { this.interceptingCatalog.Changed += value; }
remove { this.interceptingCatalog.Changed -= value; }
}

public event EventHandler<ComposablePartCatalogChangeEventArgs> Changing
{
add
{
if (this.innerNotifyChange != null)
this.innerNotifyChange.Changing += value;
}
remove
{
if (this.innerNotifyChange != null)
this.innerNotifyChange.Changing -= value;
}
add { this.interceptingCatalog.Changing += value; }
remove { this.interceptingCatalog.Changing -= value; }
}

#endregion
Expand Down
29 changes: 29 additions & 0 deletions src/MefContrib/Hosting/Filter/FilteringExportHandler.cs
@@ -0,0 +1,29 @@
namespace MefContrib.Hosting.Filter
{
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using MefContrib.Hosting.Interception;

public class FilteringExportHandler : IExportHandler
{
private readonly Func<ComposablePartDefinition, bool> filter;

public FilteringExportHandler(Func<ComposablePartDefinition, bool> filter)
{
if (filter == null) throw new ArgumentNullException("filter");

this.filter = filter;
}

public void Initialize(ComposablePartCatalog interceptedCatalog)
{
}

public IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition, IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> exports)
{
return exports.Where(export => this.filter(export.Item1));
}
}
}
1 change: 1 addition & 0 deletions src/MefContrib/MefContrib.csproj
Expand Up @@ -100,6 +100,7 @@
<Compile Include="Hosting\Conventions\ExpressionExtensions.cs" />
<Compile Include="Hosting\Conventions\IContractService.cs" />
<Compile Include="Hosting\Conventions\IExportConvention.cs" />
<Compile Include="Hosting\Filter\FilteringExportHandler.cs" />
<Compile Include="IHideObjectMembers.cs" />
<Compile Include="Hosting\Conventions\IImportConvention.cs" />
<Compile Include="Hosting\Conventions\ImportConvention.cs" />
Expand Down

0 comments on commit f50b13a

Please sign in to comment.