我了解从MEF 2开始,MEF支持将开放的泛型类型组合为封闭的类型。我正在尝试从添加到同一合成容器的两个不同程序集导出的类型组成一个封闭类型,并且我收到一个ImportCardinalityMismatchException。我对其中一个程序集使用约定,因为它不在我的控制之下。对于其他我已经使用属性。

我不确定要如何表达我的问题,因为我发现围绕泛型的术语相当混乱,但是我希望在不明确实现自己的类,从Foo继承并为其提供FooUser类型参数的情况下构成新的封闭类型。我不知道这是否与我的操作方式有关,或者是否与类型在不同程序集中有关。

在一个程序集中,我具有以下内容:

public class Foo<T> where T : Bar {}
public class Bar {}


在另一个程序集中,我具有以下内容:

[Export]
public class Bar2 : Bar {}

[Export]
public class Something
{
    [ImportingConstructor]
    public Something([Import(typeof(Foo<>))] Foo<Bar2> foo) {}
}


在我的注册码中,我执行了以下操作:

var conventions = new RegistrationBuilder();
conventions.ForType(typeof(Foo<>)).Export();

var aggregateCatalog = new AggregateCatalog();
var catalog = new AssemblyCatalog(typeof(Foo<>).Assembly, conventions);
aggregateCatalog.Catalogs.Add(catalog);

catalog = new AssemblyCatalog(typeof(Something).Assembly);
aggregateCatalog.Catalogs.Add(catalog);

catalog = new AssemblyCatalog(typeof(Bar2).Assembly);
aggregateCatalog.Catalogs.Add(catalog);

var container = new CompositionContainer(aggregateCatalog, CompositionOptions.DisableSilentRejection);
var batch = new CompositionBatch();
batch.AddExportedValue(container);
container.Compose(batch);


后来我尝试以此导出我的价值:

container.GetExportedValue<Something>();


异常:抛出:“未找到与约束匹配的出口:
    合约名称Foo(Bar2)
    RequiredTypeIdentity Foo(Bar2)”(System.ComponentModel.Composition.ImportCardinalityMismatchException)
引发了System.ComponentModel.Composition.ImportCardinalityMismatchException:“未找到与约束匹配的导出:
    合约名称Foo(Bar2)
    RequiredTypeIdentity Foo(Bar2)“

我查看了我的Conventions实例,并在容器中找到了自己的部件,即Foo {0},Bar2和Something。但是,我仍然收到System.ComponentModel.Composition.ImportCardinalityMismatchException。

我已经看到这种情况是在更抽象的情况下完成的,比如说那里有IRepository,但没有地方更具体,也没有项目跨越装配。任何帮助将不胜感激。除非有任何帮助,否则我可能只会继承那些令人反感的类型并加以处理。

编辑:我刚刚构建了上面非常详细的简化示例,但实际上我在现实世界项目中所做的事情与我在这里所做的事情有所不同,并且得到的结果相似。我已重命名了几种类型,以使其与我的简化示例保持一致。

构图产生单个构图错误。根本原因在下面提供。查看CompositionException.Errors属性以获取更多详细信息。

1)未找到符合约束条件的出口:
    ContractName CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)
    RequiredTypeIdentity CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)

结果:无法在零件'CompositionTest.Something'上设置导入'CompositionTest.Something..ctor(Parameter =“ foo”,ContractName =“ CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)”)'。
元素:CompositionTest.Something..ctor(Parameter =“ foo”,ContractName =“ CompositionTestLibrary.Foo(CompositionTestLibrary2.Bar2)”)-> CompositionTest.Something-> AssemblyCatalog(Assembly =“ CompositionTest,Version = 1.0.0.0,文化=中立,PublicKeyToken =空”)

结果:无法从零件'CompositionTest.Something'导出导出'CompositionTest.Something(ContractName =“ CompositionTest.Something”)'。
元素:CompositionTest.Something(ContractName =“ CompositionTest.Something”)-> CompositionTest.Something-> AssemblyCatalog(Assembly =“ CompositionTest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”)

最佳答案

在下面的行中,您不应使用conventions变量,因此应进行更改

catalog = new AssemblyCatalog(typeof(FooUser).Assembly, conventions);




catalog = new AssemblyCatalog(typeof(FooUser).Assembly);


在此处使用conventions不会有效地从定义了FooUserSomething的程序集中导出任何内容,因此您将无法获得Something的组合值。删除它将允许导出和构成Something

09-09 17:07