AddSingleton<>() vs AddSingleton()

7

我正在我的项目中实现依赖注入。我发现有两种方法可以添加单例服务:

services.AddSingleton(new MyCustomService())

并且
services.AddSingleton<MyCustomService>()

两种方法都似乎可行。这两种方法的区别是什么,我应该使用哪一种方法?
3个回答

5
使用通用的 .AddSingleton<TService>() 方法(以及 .AddSingleton<TService, TImplementation>())时,类型由容器创建、控制和处理。如果构造函数包含其他依赖项,则这些依赖项会自动注入(一种称为“自动装配”的技术)。
使用 .AddSingleton<TService>(TService) 提供的实例已经存在。在这种情况下,当实现了 IDisposableIAsyncDisposable 时,容器不会处理该实例。您需要自行处理该实例的处理。
由于使用 .AddSingleton<TService>(TService) 提供了一个已经存在的实例,因此容器无法注入任何依赖项,因为为了做到这一点,它也必须创建该实例。
当使用 .AddSingleton<TService>(Func<TService>) 方法注册实例时,Func<TService> 委托控制依赖项的创建,但委托返回的实例仍然由容器跟踪和处理。

.AddSingleton<TService>(Func<IServiceProvider,TService>) 怎么样?我猜想使用该方法时,类型也会由容器创建、控制和处理。这是正确的吗?即使我使用显式的 new,例如 services.AddSingleton<MyCustomService>(_ => new MyCustomService()),对吗? - Joerg

1
根据第一个示例中的docs,您正在使用AddSingleton<TService>(IServiceCollection, TService)扩展方法,在第二个示例中使用AddSingleton<TService>(IServiceCollection)
这两者之间的区别在于创建TService实例的时间。在第一个示例中 - 注册时创建它。在第二个示例中 - 它将在第一次请求时由容器创建。
你可以自行决定使用哪个。但是,如果您的MyCustomService可能具有其他依赖项,则我想AddSingleton<TService>(IServiceCollection)可能更方便。

0
简短回答:显式加载服务与通过配置使用泛型从注入中提取之间的区别。
在第一种情况下,您正在添加一个SingletonService,您自己实例化它。而在第二种情况下,您正在请求依赖注入根据配置加载MyCustomService。当应用程序的不同配置可能有不同版本的MyCustomService时,后者非常有用。
另一种看待它的方式是,第一种方式是加载单例,并在没有单例时失败。而第二种方式是使用泛型来验证服务类型,如果在配置中没有指定,则会出现错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接