Создание нескольких экземпляров импортированных частей 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.