加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在MEF 2中使用闭合类型编写开放式通用类型

发布时间:2020-12-15 22:00:17 所属栏目:百科 来源:网络整理
导读:据我所知,从MEF 2开始,MEF支持将开放泛型类型组合成封闭类型.我正在尝试从添加到同一组合容器的两个不同程序集中导出的类型中组合一个封闭类型,并且我收到一个ImportCardinalityMismatchException.我正在使用其中一个程序集的约定,因为它不在我的控制之下.对
据我所知,从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>();

异常:抛出:“未找到与约束匹配的导出:
????ContractName Foo(Bar2)
????RequiredTypeIdentity Foo(Bar2)“(System.ComponentModel.Composition.ImportCardinalityMismatchException)
抛出了System.ComponentModel.Composition.ImportCardinalityMismatchException:“未找到与约束匹配的导出:
????ContractName Foo(Bar2)
????RequiredTypeIdentity Foo(Bar2)“

我查看了我的约定实例,在容器中我有我的部分,即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,Culture = neutral,PublicKeyToken = null”)

导致:无法从“CompositionTest.Something”部分导出’CompositionTest.Something(ContractName =“CompositionTest.Something”)’.
元素:CompositionTest.Something(ContractName =“CompositionTest.Something”) – > CompositionTest.Something – > AssemblyCatalog(Assembly =“CompositionTest,PublicKeyToken = null”)

解决方法

在以下行中,您不应使用约定变量,因此您应该更改

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

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

在这里使用约定实际上不会从定义FooUser和Something的程序集中导出任何东西,因此您将无法获得Something的组合值.删除它将允许导出和组合某些东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读