IoC - Динамическая Композиция экземпляров объекта - PullRequest
2 голосов
/ 10 июня 2010

Есть ли способ использовать IoC, MEF [Imports] или другое решение DI для создания зависимостей на лету во время создания объекта, а не во время создания?

Вот моя текущая мысль.Если у вас есть экземпляр объекта, который вызывает события, но вы не создаете объект один раз и не сохраняете его в памяти, вы должны регистрировать обработчики событий каждый раз, когда создается объект.Насколько я могу судить, большинство IoC-контейнеров требуют, чтобы вы зарегистрировали все классы, используемые в композиции, и вызвали Compose (), чтобы он перехватывал все зависимости.

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

Может бытьЯ немного перепутал терминологию, но моя цель состоит в том, чтобы не писать фреймворк, чтобы «подключить все события» к экземпляру объекта, и использовать что-то вроде MEF для [Export] обработчиков (зависимостей), которые придерживаются очень специфическогоинтерфейс и [ImportMany] их в экземпляр объекта, поэтому мой экспорт вызывается, если сборки присутствуют при запуске приложения.Поэтому, возможно, все объекты все еще могут быть скомпонованы при запуске приложения, но я хочу, чтобы система находила и вызывала их все по мере создания и уничтожения объекта.

1 Ответ

4 голосов
/ 10 июня 2010

Как правило, способ обработки экземпляров на лету в среде DI / IoC заключается в использовании абстрактных фабрик. Фабрика - это класс only , которому разрешено напрямую взаимодействовать с контейнером для разрешения зависимостей при создании нового объекта.

public interface IWidgetFactory
{
    IWidget CreateWidget(...);
}

public class MyIocWidgetFactory : IWidgetFactory
{
    private IoCContainer container;

    public MyIocWidgetFactory(IoCContainer container)
    {
        if (container == null)
            throw new ArgumentNullException("container");
        this.container = container;
    }

    public IWidget CreateWidget(...)
    {
        // Assumes that the container is configured to create transient objects
        // for IWidget, not a singleton.
        return container.Resolve<IWidget>();
    }
}

Пожалуйста, не путайте это с анти-паттерном поиска сервисов; ничто другое не может касаться контейнера, кроме фабрики, и он создает только один тип объекта.

На этом этапе вы просто передаете IWidgetFactory тому, что необходимо для создания виджета во время выполнения. Вот и все - вы поддерживали DI.

...