Я понимаю, что начиная с 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..ctor (Parameter = "foo", ContractName = "CompositionTestLibrary.Foo (CompositionTestLibrary2.Bar2)")' в части 'CompositionTest.Something'. Элемент: CompositionTest.Something..ctor (Parameter = "foo", ContractName = "CompositionTestLibrary.Foo (CompositionTestLibrary2.Bar2)") -> CompositionTest.Something -> AssemblyCatalog (Assembly = "CompositionTest, Version = 1.0.0.0, Культура = нейтральный, PublicKeyToken = null ")
Результат: Невозможно получить экспорт 'CompositionTest.Something (ContractName = "CompositionTest.Something")' из части 'CompositionTest.Something'. Элемент: CompositionTest.Something (ContractName = "CompositionTest.Something") -> CompositionTest.Something -> AssemblyCatalog (Assembly = "CompositionTest, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null")
conventions
с правильной сборкой, то есть той, в которой определеноFoo<T>
? - person Adi Lester   schedule 07.01.2014