Создание нескольких экземпляров импортированных частей MEF
В настоящее время мое приложение WPF импортирует часть, подобную этой
[Import(typeof(ILedPanel)]
public ILedPanel Panel { get; set; }
Но это дает одно единство класса, реализующего ILedPanel.
То, что я действительно хочу сделать, - это возможность создавать столько экземпляров
что мне нужно. Обратите внимание, что включен только один экспорт для ILedPanel.
с программным обеспечением в любой момент времени.
(Если я использую импорт со списком, который дает мне один экземпляр
для каждого класса, реализующего ILedPanel)
Любые предложения?
Ответы
Ответ 1
В MEF сегодня нет поддержки встроенной поддержки, но перед возвратом в Service Locator вы можете найти некоторое вдохновение здесь: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx
Существенная идея заключается в том, что вы "импортируете" контейнер в компонент, который должен выполнять динамическую инстанцию.
Более прямая поддержка этого сценария - это то, что мы изучаем.
Ник
ОБНОВЛЕНИЕ: Теперь у MEF есть экспериментальная поддержка. См. этот пост в блоге для получения дополнительной информации.
Ответ 2
Я не уверен, что это то, о чем говорит Николас, но вы можете импортировать класс Factory, а не класс экземпляра, например:
[Import(typeof(ILedPanelFactory)]
public ILedPanelFactory PanelFactory { get; set; }
... и затем в вашем коде...
ILedPanel panel = PanelFactory.BuildPanel();
Ответ 3
Все остальные ответы довольно старые, поэтому они не упоминают относительно новую функцию в MEF, называемую ExportFactory
. Этот универсальный класс позволяет вам импортировать ExportFactory<ILedPanel>
и создавать как можно больше экземпляров, когда вам это нужно, поэтому ваш код будет выглядеть так:
[Import(typeof(ILedPanel)]
public ExportFactory<ILedPanel> PanelFactory { get; set; }
public ILedPanel CreateNewLedPanelInstance()
{
return PanelFactory.CreateExport().Value;
}
Этот метод также удовлетворяет любым импортам, которые создали часть. Вы можете больше узнать об использовании класса ExportFactory
здесь.
Ответ 4
Если я не понял вопрос, похоже, он был бы решен просто с помощью CreationPolicy.NonShared.
Это предполагает, что код, объявляющий Panel, существует везде, где вы хотите панель. Вы бы получили новый экземпляр ILedPanel в каждом экземпляре каждого класса, у которого было это объявление (импорт).
Ответ 5
Я думаю, вы имеете в виду, что хотите использовать MEF в этом случае, как локатор сервисов, а не контейнер инъекций зависимостей. Попробуйте посмотреть примеры для ValueResolver
Ответ 6
Глядя на образец игры с фигурами, который поставляется с MEF, есть класс ShapeFactory:
[Export]
public class ShapeFactory
{
private readonly Random random = new Random((int)DateTime.Now.Ticks);
[Import]
private ICompositionService CompositionService { get; set; }
public IShape GetRandomShape()
{
var shapeRetriever = new ShapeRetriever();
CompositionService.SatisfyImports(shapeRetriever);
int randomIndex = random.Next(shapeRetriever.PossibleShapes.Length);
return shapeRetriever.PossibleShapes[randomIndex].GetExportedObject();
}
private class ShapeRetriever
{
[ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)]
public Export<IShape, IShapeMetadata>[] PossibleShapes { get; set; }
}
}
Что демонстрирует создание экземпляров случайной формы "по запросу"... Я бы подумал, что в вашем сценарии вы можете сделать что-то подобное без выбора случайной реализации, так как вы предполагаете, что будет зарегистрирована только одна реализация зарегистрированного ILedPanel.