Создание нескольких экземпляров импортированных деталей MEF - PullRequest
11 голосов
/ 04 июня 2009

В настоящее время мое приложение WPF импортирует такую ​​деталь

[Import(typeof(ILedPanel)]
public ILedPanel Panel { get; set; }

Но это дает ма единственный экземпляр класса, который реализует ILedPanel. Что я действительно хочу сделать, так это иметь возможность создавать как можно больше экземпляров. что мне нужно Обратите внимание, что включен только один экспорт для ILedPanel с программным обеспечением в любой момент времени.

(Если я использую импорт со списком, который дает мне один экземпляр для каждого класса, реализующего ILedPanel)

Есть предложения?

Ответы [ 6 ]

10 голосов
/ 04 июня 2009

Я не уверен, что это то, на что ссылается Николас, но вы можете импортировать класс Factory, а не класс экземпляра, например:

[Import(typeof(ILedPanelFactory)]
public ILedPanelFactory PanelFactory { get; set; }

... а потом в вашем коде ...

ILedPanel panel = PanelFactory.BuildPanel();
9 голосов
/ 04 июня 2009

В MEF сегодня нет «встроенной» поддержки для этого, но перед возвратом в сервисный локатор вы можете найти здесь некоторое вдохновение:

Основная идея заключается в том, что вы 'импортируете' контейнер в компонент, который должен выполнять динамическую реализацию.

Более прямая поддержка этого сценария - это то, что мы изучаем.

Ник

ОБНОВЛЕНИЕ: MEF теперь имеет экспериментальную поддержку для этого. См. эту запись в блоге для получения дополнительной информации.

8 голосов
/ 20 ноября 2013

Все остальные ответы довольно старые, поэтому они не упоминают относительно новую функцию в MEF, которая называется ExportFactory. Этот универсальный класс позволяет вам импортировать ExportFactory<ILedPanel> и создавать столько экземпляров, сколько вам нужно, когда вам это нужно, поэтому ваш код будет выглядеть так:

[Import(typeof(ILedPanel)]
public ExportFactory<ILedPanel> PanelFactory { get; set; }

public ILedPanel CreateNewLedPanelInstance()
{
    return PanelFactory.CreateExport().Value;
}

Этот метод также удовлетворяет любому импорту, который имеет созданная деталь. Вы можете узнать больше об использовании ExportFactory класса здесь .

5 голосов
/ 24 июля 2009

Если я не понимаю вопрос, похоже, что его можно решить, просто используя CreationPolicy.NonShared.

Это предполагает, что код, объявляющий Panel, существует везде, где вы хотите панель. Вы получите новый экземпляр ILedPanel в каждом экземпляре каждого класса, который имеет это объявление (импорт).

3 голосов
/ 10 июля 2009

Глядя на образец игры с формами, который поставляется с 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.

2 голосов
/ 04 июня 2009

я думаю, вы имеете в виду, что вы хотите использовать MEF в этом случае как локатор службы, а не как контейнер внедрения зависимости. Попробуйте посмотреть примеры для ValueResolver

...