Когда MEF видит импорт типа ExportFactory<IFoo>
, он обрабатывает это особым образом. Вместо буквального поиска экспорта ExportFactory<IFoo>
он ищет экспорт IFoo
и волшебным образом генерирует фабрику для этого типа.
Ваша ошибка в том, что вы ожидаете, что эта магия также автоматически сработает для вашей собственной альтернативы ExportFactory
, которую вы назвали SrviceProviderFactory
. Это неправда. Когда вы импортируете SrviceProviderFactory<IFoo,IFooMetadata>
куда-то, MEF буквально ищет экспорт этого типа.
Простое решение - предоставить ему этот экспорт. Вручную экспортируйте фабрику для каждой реализации IServiceProvider. Например, если у вас есть FooServiceProvider
:
public class FooServiceProvider : IServiceProvider
{
public FooServiceProvider(Dependency dependency)
{
...
}
}
Тогда вам также нужно иметь FooServiceProviderFactory:
[Export(typeof(IServiceProviderFactory))]
[ExportMetaData("foo", "bar")]
public class FooServiceProviderFactory : IServiceProviderFactory
{
public IServiceProvider CreateServiceProvider(Dependency d)
{
return new FooServiceProvider(d);
}
}
И тогда ваш импортер может выбрать правильную фабрику на основе метаданных:
public class FactoryUser
{
[ImportMany]
public Lazy<IServiceProviderFactory,IDictionary<string,object>>[] Factories
{
get;
set;
}
public void DoSomething()
{
var factory = Factories.First(x => x.Metadata["foo"] == "bar").Value;
var serviceProvider = factory.CreateServiceProvider(someDependency);
...
}
}
Раздражает то, что для каждой реализации поставщика услуг вам также необходимо создать и экспортировать реализацию фабрики. Вы можете сохранить работу, создав общий фабричный базовый класс (например, SrviceProviderFactory
), но вам все равно придется извлекать определенные классы, потому что вы не можете использовать параметры универсального типа в экспортах MEF. обновление : Я считаю, что .NET 4.5 теперь поддерживает экспорт открытых универсальных типов.
Вот почему Я уже предлагал вам экспортировать Func
вместо , но, видимо, вам не понравился этот ответ.
Вы также можете попытаться повторить магию ExportFactory
. Это возможно, но очень продвинутый вариант использования MEF. Если вы хотите сделать это, я предлагаю вам взглянуть на источники MEF ExportFactoryProvider
, чтобы узнать, как создать собственную реализацию с поддержкой параметров.