Можно ли смешивать образ жизни с автоматическим подключением в Simple Injector? - PullRequest
1 голос
/ 14 апреля 2020

Я использую Simple Injector, чтобы позволял моему коду автоматически подключаться к сообщениям шины событий . Во время автоматической проводки моего INotificationHandlers я разрешил потенциальное использование разных стилей жизни для разных конкретных реализаций, как показано здесь:

public static Lifestyle GetLifestyleForType(
    Type type, Container container, Dictionary<Type,Lifestyle> list = null)
{
    if (list is null) return container.Options.DefaultLifestyle;

    return list.TryGetValue(type, out var lifestyle)
        ? lifestyle : container.Options.DefaultLifestyle;
}

public static void Wire(Container container)
{
    var lifestyles = new Dictionary<Type, Lifestyle> {
        { typeof(FirstClass), Lifestyle.Singleton },
        { typeof(OtherClass), Lifestyle.Transient }
    };

    var handlerTypes = container
        .GetTypesToRegister(typeof(INotificationHandler<>), typeof(OtherClass).Assembly);

    var handlerProducers = (
        from type in handlerTypes
        from interfaceType in type.GetClosedTypesOf(typeof(INotificationHandler<>))
        let producer = GetLifestyleForType(type, container, lifestyles)
            .CreateProducer(interfaceType, type, container)
        group new { type, producer } by interfaceType into interfaceGroup
        select new
        {
            interfaceGroup.Key,
            Value = (
                from pair in interfaceGroup
                group pair.producer by pair.type into concreteGroup
                select new { concreteGroup.Key, Value = concreteGroup.ToArray() })
                .ToDictionary(i => i.Key, i => i.Value)
        }).ToDictionary(i => i.Key, i => i.Value);
}

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

Кроме того, Lifestyle.Transient работает по-другому с async/await операторами? Только что осознал, что использовал жизненный цикл Transient вместе с SimpleInjector без каких-либо наблюдаемых побочных эффектов, о которых я знаю, и я полагаю, что по умолчанию я должен переключиться (как я описал выше) на Lifestyle.Scoped и container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle()

1 Ответ

1 голос
/ 15 апреля 2020

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

По умолчанию Simple Injector использует Transient в качестве стиля жизни по умолчанию. Это означает, что, если вы явно не укажете регистрацию с образом жизни, Simple Injector будет использовать стиль жизни по умолчанию, то есть Transient.

Хотя по сути, нет ничего плохого в использовании нескольких стилей жизни для ваших обработчиков, использование нескольких стилей жизни делает увеличьте сложность своего решения (как вы, вероятно, уже заметили), поэтому вам следует спросить себя, действительно ли вам нужна эта сложность. Если только вы не sh сделаете свои графы объектов синглетонами сверху вниз (но это приведет к совершенно другой модели ), я предлагаю сохранить решение простым и придерживаться использования Transient. Как общее практическое правило, укажите свои root типы (обработчики, контроллеры, модели представления и т. Д. c) Transient.

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

Но эти проблемы можно легко решить, перемещая любые логи c относительно удаления и кэширования зависимостей типов root. Вы можете сделать эти зависимости Scoped или даже Singleton. Я бы вообще хмурился на любой обработчик в системе, который реализует IDisposable или кэширует любое состояние внутри. Если убрать логику c из ваших обработчиков - не только - «обойти» ограничения образа жизни Transient, я бы сказал, что это приводит к созданию более продуманной системы. Это также упрощает анализ ваших обработчиков; что они могут и не могут сделать, и каков их образ жизни. Самый простой способ понять любого разработчика, работающего с системой (и любого будущего разработчика), - это когда все обработчики всегда ведут одинаковый образ жизни.

Кроме того, Lifestyle.Transient работает по-разному с операторами async / await. ?

Образ жизни Transient - самый простой образ жизни; для простого инжектора Transient просто не работает. Экземпляр создан и забыт (он не отслеживается). Он не будет работать по-другому при работе в асинхронной операции.

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