简易注射器中混合生活方式与自动接线可以吗?

问题描述 投票:1回答:1

我正在使用简单的注射器,以 使我的代码能够自动连接到事件总线消息。. 在我的自动布线过程中 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.Scopedcontainer.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle()

c# .net simple-injector
1个回答
1
投票

我注意到,在所有其他的自动布线示例中,它假设使用了相同的生活方式(因为没有看到指定的生活方式)--这有什么原因吗(为了防止做危险的事情)?

默认情况下,Simple Injector使用 Transient 作为其默认的生活方式。这意味着,除非您明确地提供一个带有生活方式的注册,否则 Simple Injector 将使用默认的生活方式,即。Transient.

虽然为您的处理程序使用多种生活方式并没有什么本质上的错误,但使用多种生活方式确实增加了您的解决方案的复杂性(您可能已经注意到了),所以您应该问问自己是否真的需要这种复杂性。除非你想让你的对象图从上到下都是单体的(但那会导致 殊途同归),我建议简化解决方案,坚持使用 Transient 来代替。作为一般的经验法则,让你的根类型(处理程序、控制器、视图模型等)成为 Transient.

Transient 生活方式虽然会带来一些后果。Transient 组件没有处理掉,而且由于 Transient 组件不被重用,它们不能用于任何数据的缓存。

但这些问题可以通过将任何有关处理和缓存的逻辑转移到根类型的依赖关系中来轻松解决。你可以让这些依赖关系 Scoped 甚至 Singleton. 我通常会对系统中任何实现了 IDisposable 或在内部缓存任何状态。将这些逻辑从处理程序中移出,不仅可以 "绕过 "了 Transient 的生活方式,我认为这将导致一个更好的设计系统。这也使你更容易推理你的处理程序;他们能做什么,不能做什么,以及他们的生活方式是什么。对于任何在系统中工作的开发人员(以及任何未来的开发人员)来说,最容易理解的是当所有的处理程序总是具有相同的生活方式。

另外Lifestyle.Transient与asyncawait操作者的工作方式是否不同?

Transient 生活方式是最简单的生活方式,对于简单的注射器 Transient 就是一个没有操作。实例被创建并被遗忘(它没有被跟踪)。在异步操作中运行时不会有任何不同。

© www.soinside.com 2019 - 2024. All rights reserved.