当两个类都注册为单例时,简单注射器会产生生活方式不匹配错误

时间:2018-10-25 11:03:43

标签: inversion-of-control simple-injector

所以我有这个简单的喷油器IoC连线代码

container.RegisterSingleton<IMsgProcessor, PrometheusTickerPublisher>();
container.RegisterSingleton<ICollector, UpdatesPerSecondDataCollector>();

当我尝试运行我的应用程序时,我收到此错误消息

  

遇到生活方式不匹配的情况。 PrometheusTickerPublisher   (单一)取决于UpdatesPerSecondDataCollector(瞬态)。   生活方式的不匹配可能会导致应用程序中的并发错误。   请参阅https://simpleinjector.org/dialm以了解此问题   以及解决方法。

我一点都不明白。两项都注册为单例。然后,我将注册更改为此,以查看是否可以更明确地了解它是单例

container.RegisterSingleton<IMsgProcessor, PrometheusTickerPublisher>();
container.AddRegistration(typeof(ICollector), CreateCollectorRegistration(container));

internal static Registration CreateCollectorRegistration(Container container)
{
    return
        Lifestyle.Singleton.CreateRegistration<ICollector>(
            () =>
            {
                var timeProvider = container.GetInstance<ITimeProvider>();
                return new UpdatesPerSecondDataCollector(timeProvider);
            }, container);
}

但这会给出相同的错误

这时我完全迷失了,任何想法

2 个答案:

答案 0 :(得分:2)

在注册过程结束时调用Container.Verify()将检查容器的health。如果这样做,它将为您提供更多反馈:

  

配置无效。报告了以下诊断警告:

     

-[生活方式不匹配] PrometheusTickerPublisher(Singleton)取决于UpdatesPerSecondDataCollector(瞬态)。

     

-[短路依赖性] PrometheusTickerPublisher可能错误地依赖于未注册的类型UpdatesPerSecondDataCollector(瞬态)而不是ICollector(Singleton)。

     

-[歧义的生活方式] UpdatesPerSecondDataCollector(瞬态)的注册与ICollector(Singleton)的注册映射到相同的实现(UpdatesPerSecondDataCollector),但是注册映射到不同的生活方式。这将导致每次注册解析为不同的实例。

     

-[歧义的生活方式] IUpdate(Singleton)的注册与UpdatesPerSecondDataCollector(Transient)的注册映射到相同的实现(UpdatesPerSecondDataCollector),但是注册映射到不同的生活方式。这将导致每个注册解析为不同的实例。   有关警告的详细信息,请参见Error属性。

     

请参阅https://simpleinjector.org/diagnostics如何解决问题以及如何禁止个别警告。

这里最有趣的部分是Short Circuited Dependency warning

  

-[短路依赖性] PrometheusTickerPublisher可能错误地依赖于未注册的类型UpdatesPerSecondDataCollector(瞬态)而不是ICollector(单一)。

换句话说,Simple Injector检测到您通过UpdatesPerSecondDataCollectorICollector注册为Singleton,但是您通过直接依赖于{{ 1}}实现。之所以称为短路,是因为您直接使用(未注册)实现而不是使用ICollector注册。这可能会引起各种各样的问题。

由于UpdatesPerSecondDataCollector没有显式注册,因此Simple Injector会为您隐式注册它,并且它使用ICollector的生活方式(除非您另外指定)。但是,UpdatesPerSecondDataCollector的注册是Transient,因此可能会引起问题。再次在Ambiguous Lifestyles warning中指出:

  

-[歧义的生活方式] UpdatesPerSecondDataCollector(瞬态)的注册与ICollector(Singleton)的注册映射到相同的实现(UpdatesPerSecondDataCollector),但是注册映射到不同的生活方式。这将导致每次注册解析为不同的实例。

无需致电ICollector,所有这些问题都不会被发现。 Simple Injector解析类型时唯一要做的验证是Lifestyle Mismatch,这就是为什么您仅收到以下错误的原因:

  

遇到生活方式不匹配的情况。 PrometheusTickerPublisher(Singleton)依赖于UpdatesPerSecondDataCollector(瞬态)。

长话短说,您并不是单独注册Singleton,而是仅仅注册了Verify抽象,这导致简单注入程序隐式为UpdatesPerSecondDataCollector进行ICollector注册代表你。由于此注册是Transient,因此Simple Injector阻止了将其注入到UpdatesPerSecondDataCollectorTransient中。如果您会打电话给Singleton,那么将会有非常详细的问题描述,指出发生了什么问题,而不仅仅是一个简单的生活方式不匹配。

答案 1 :(得分:0)

好吧,所以我发现了问题所在,我的班级期望的是确切的UpdatesPerSecondDataCollector类型而不是ICollector,所以我想因为我没有明确地注册类型,所以它被解析为每次由SimpleInjector瞬变。解决方案只是在IOC注册中做到这一点

container.RegisterSingleton<UpdatesPerSecondDataCollector>();

那是我的下游课程所期望的

关闭案例