Простой Инжектор: RegisterInitializer не всегда срабатывает - PullRequest
1 голос
/ 24 июня 2011

Я использую метод RegisterInitializer для добавления свойств в базовые типы следующим образом:

container.RegisterInitializer<BaseHandler>(handler =>
{
    handler.Context = container.GetInstance<HandlerContext>();
});

Это прекрасно работает, но RegisterInitializer не срабатывает на всех зарегистрированных типах, которые наследуются от BaseHandler,Кажется, он не запускается, когда я сам звоню new:

var url = ConfigurationManager.AppSettings["NotificationServiceUrl"];
container.Register<Handler<NotifyCustomerMessage>>(() => 
    new NotifyCustomerHandler(url));

// many other Handler<T> lines here

Почему это так и как я могу решить эту проблему?

1 Ответ

2 голосов
/ 24 июня 2011

ОБНОВЛЕНИЕ

Это поведение изменилось в Простой инжектор 2 : инициализаторы теперь также будут запускаться при Func<T> регистрациях.Причина в том, что Simple Injector теперь имеет явную поддержку образа жизни и теперь фактически ведет себя как StructureMap (как описано ниже).


Ваше наблюдение верно.Документация Simple Injector описывает примерно так:

Примечание. Контейнер не сможет вызвать делегат инициализатора для типа, который создается вручную с помощью оператора new,По возможности используйте автоматическое внедрение конструктора.

Лучший способ преодолеть эту проблему - позволить Simple Injector использовать автоматическое внедрение конструктора.

Ваш NotifyCustomerHandler принимает аргумент конструктора string, что делает невозможным автоматическое внедрение конструктора.Ваш NotifyCustomerHandler, кажется, имеет несколько обязанностей .Абстрагируйте службу уведомлений от функциональности обработчика, скрыв эту службу за интерфейсом INotificationService и разрешив обработчику зависеть от этого интерфейса.Вы можете затем внедрить это значение конфигурации в службу уведомлений.

Некоторая справочная информация о том, почему Simple Injector ведет себя таким образом

Хотя другие структуры DI(например, StructureMap с его методом OnCreationForAll) вызовет делегат, даже когда вы создаете новый тип, а Simple Injector - нет.Это вызвано разницей, в которой фреймворки ожидают от пользователей регистрации стиля жизни.

С StructureMap образ жизни настраивается путем явного вызова метода LifecycleIs.Ожидается, что с помощью простого инжектора пользователи будут настраивать образ жизни, регистрируя делегатов, которые сами реализуют образ жизни.Посмотрите, например, на Пример образа жизни в потоке в документации.С StructureMap это среда, которая контролирует время жизни для вас, в то время как с Simple Injector это часто зависит от пользователя.

Другими словами, StructureMap ожидает, что зарегистрированный делегат всегда будет создавать новый экземпляр, тогда как Simple Injectorне имеет этого ожидания.Поскольку StructureMap ожидает возврата нового экземпляра, он может безопасно инициализировать этот объект после вызова делегата.Кэширование экземпляров выполняется в другом месте.Однако Simple Injector не будет вызывать инициализатор для объектов, возвращаемых таким делегатом, просто потому, что это может привести к повторной инициализации одного и того же объекта снова и снова, что может вызвать непредвиденное поведение приложения и возможные проблемы с производительностью.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...