【问题标题】:AddSingleton<>() vs AddSingleton()AddSingleton<>() 与 AddSingleton()
【发布时间】:2020-09-16 13:18:45
【问题描述】:
我正在我的项目中实现依赖注入。我遇到了两种添加单例服务的方法 -
services.AddSingleton(new MyCustomService())
和
services.AddSingleton<MyCustomService>()
这两种方法似乎都有效。这两种方法有什么区别,我应该使用哪一种?
【问题讨论】:
标签:
c#
asp.net-core
.net-core
dependency-injection
【解决方案1】:
当使用泛型.AddSingleton<TService>() 方法(和.AddSingleton<TService, TImplementation>(),该类型由容器创建、控制和处置。当构造函数包含其他依赖项时,这些依赖项会自动注入(一种称为“Auto-接线”)。
使用.AddSingleton<TService>(TService) 提供的实例已经存在。在这种情况下,容器在实现 IDisposable 或 IAsyncDisposable 时将不处理该实例。您有责任自己处置该实例。
由于.AddSingleton<TService>(TService) 提供了一个已经存在的实例,容器不能注入任何依赖项,因为为了做到这一点,它还必须创建该实例。
【解决方案2】:
根据第一个示例中的docs,您使用的是AddSingleton<TService>(IServiceCollection, TService) 扩展方法,而在第二个示例中 - AddSingleton<TService>(IServiceCollection)。
这2个的区别是TService的实例被创建的时间。在第一个 - 您在注册时创建它。在第二个中 - 它将在第一次请求时创建为容器。
由您决定应该使用哪一个。但是,如果您的 MyCustomService 可能有其他依赖项 - 我猜 AddSingleton<TService>(IServiceCollection) 可能更方便。
【解决方案3】:
简答:显式加载服务与使用泛型通过配置从注入中提取。
在第一个实例中,您正在添加一个您自己实例化的 SingletonService。在第二个中,您要求依赖注入基于配置加载 MyCustomService。当您可能针对应用程序的不同配置使用不同版本的 MyCustomService 时,后者很有用。
另一种看待它的方式。第一个是加载单例,如果不是则失败。第二种是使用泛型来验证服务的类型,如果没有在配置中指定就会爆炸。