通用接口未使用MEF RegistrationBuilder导入

时间:2015-12-12 11:50:49

标签: c# mef

我尝试导出以下界面:

public interface ITree<T> where T : IComparable

实现接口的类:

public class Tree<T> : ITree<T> where T : IComparable

在单元测试类中,我执行以下操作:

[TestClass]
public class TreeTest 
{
    [TestInitialize()]
    public void InitialTest()
    {
        RegistrationBuilder registrationITreeBuilder = new RegistrationBuilder();
        //export all classes which implement ITree
        registrationITreeBuilder.ForTypesMatching(t => t.GetInterface(typeof(ITree<>).Name) != null).Export<ITree<int>>();
        registrationITreeBuilder.ForType<TreeTest>().ImportProperty(p => p.TreeInstances,ib=>ib.AsMany(true)); //TreeTest - the unit test class

        var catalog = new AggregateCatalog(
            new AssemblyCatalog(Assembly.GetExecutingAssembly(), registrationTreeTestBuilder), //unit test project
            new AssemblyCatalog(typeof(ITree<>).Assembly, registrationITreeBuilder)
            );

        //Create the current composition container to create the parts
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }
    public IEnumerable<ITree<int>> TreeInstances { get; set; }
}

执行InitialTest()方法后,属性TreeInstances为 null 。将容器添加到手表时,我会在container.Catalog.Parts

下看到
  

{Get.the.Solution.DataStructure.Tree({0})}

ExportDefinition (ContractName="Get.the.Solution.DataStructure.ITree(System.Int32)")}应该是正确的。但是,虽然我设置了ImportProperty定义,但没有ImportDefinition。

任何人都知道如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

ComposeParts(...)调用实际上是由MEF的属性编程模型使用。您在单元测试中使用的是使用基于约定的编程模型。

我个人不会混用这两个,但是如果你想在这里快速修复,只需将[ImportMany]属性添加到TreeInstances属性中,你的测试项目就可以了。

我建议在此处使用单独的类型来托管树实例,将其导出到构建器中,并通过GetExportedValue调用从测试中的容器中获取它。这意味着您的测试类看起来像这样:

[TestClass]
public class TreeTest
{
    private CompositionContainer _Container;

    private class Trees
    {
        public IEnumerable<ITree<int>> TreeInstances { get; set; }
    }

    [TestInitialize()]
    public void InitialTest()
    {
        ...
        //add the Export<Trees>() in your code
        registrationITreeBuilder.ForType<Trees>().ImportProperty(tt => tt.TreeInstances, ib => ib.AsMany()).Export<Trees>();
        ...
    }

    [TestMethod]
    public void TestMethod1()
    {
        var trees = _Container.GetExportedValue<Trees>();
    }
}

通过这种方式,您还可以为测试添加一个清理方法,以便在您分配了需要处理的资源时摆脱CompositionContainer