В руководстве по программированию MEF прочитайте раздел Экспорт и метаданные . Он показывает, как вы можете добавить метаданные в экспортируемую деталь, используя атрибут ExportMetadata
или определив свой собственный атрибут экспорта.
Затем вы можете определить ILoggerMetadata
интерфейс следующим образом:
public interface ILoggerMetadata
{
string Catagory { get; }
}
и сделайте ImportMany
из IEnumerable<Lazy<ILogger,ILoggerMetadata>>
и выберите тот, который вы хотите в коде, например:
private ILogger fooLogger;
[ImportMany]
public IEnumerable<Lazy<ILogger,ILoggerMetadata>> Loggers
{
set
{
this.fooLogger = value.First(x => x.Metadata.Catagory == "foo").Value;
}
}
Я согласен, что было бы лучше поместить ограничения метаданных непосредственно в атрибут импорта, но в настоящее время это невозможно в MEF "из коробки". (Возможно, для этого можно расширить MEF.)
Другой подход - извлечь интерфейс IFooLogger
из ILogger
и использовать его при импорте и экспорте. Это просто и имеет тот же эффект, что и ограничение импорта. Однако этот подход не работает, если у вас есть несколько атрибутов метаданных и / или много возможных значений.
edit: Я немного неправильно понял ваш вопрос; Я думал, что речь идет об ограничении импорта, а не о настройке импортированного объекта с некоторыми дополнительными параметрами.
Я думаю, это недавнее сообщение Кэтлин Доллард о той же проблеме. Кроме того, в этом посте о связях компонентов Николас Блумхардт моделирует такое отношение "параметризации", как внедрение Func<X,Y>
(или Func<ILogger,string>
в вашем случае).
Вы можете сделать то же самое в MEF, поместив атрибут [Export(typeof(Func<ILogger,string>))]
непосредственно в метод. Или, если вам нужен менее двусмысленный контракт, вы можете определить интерфейс ILoggerFactory
и импортировать / экспортировать его так:
public ILoggerFactory
{
ILogger Create(string category);
}
В конце вам все равно придется вызывать фабрику в коде.