AddSingleton(S,T)而不是AddSingletn(T)的好处



使用services.AddSingleton<SomeService, SomeServiceImplementation>()而不是services.AddSingleton<SomeServiceImplementation>()有什么好处?

例如,我有一个示例接口

interface ISampleInterface
{
void DoSomething();
}

和一个示例类:

class SampleClass : ISampleInterface
{
public void DoSomething()
{
console.write("hi");
}
}

不,我做services.AddSingleton<SampleClass>()

为什么或何时使用services.AddSingleton<ISampleInterface, SampleClass>()

谢谢你的帮助!:-(

services.AddSingleton<SampleInterface, SampleClass>()允许您为同一接口注册不同的实现,而无需修改代码的其余部分。

以最小的工作量更改实施

假设您有一个ILogger接口和实现,可以将日志记录到浏览器控制台,或者将日志条目发送到不同的服务,例如ConsoleLoggerMyServiceLoggerPrometheusLogger。如果您只注册了实现,例如services.AddSingleton<ConsoleLogger>(),那么每次更改记录器实现时,您都必须更改所有类。

你必须转到每一页并更改

@inject ConsoleLogger logger;

@inject MyServiceLogger logger;

忘记在运行时指定记录器。每次想要使用新的日志记录服务时,都必须部署应用程序。

通过注册接口和特定的实现,您的所有类都可以继续使用ILogger<T>,并且永远不会知道实现已经更改。

运行时的实施选择

您甚至可以在运行时根据环境变量、配置或您想要的任何其他逻辑来更改实现,例如:

if (app.IsDevelopment)
{
services.AddSingleton<ILogger,ConsoleLogger>();
}
else
{
services.AddSingleton<ILogger,MyServiceLogger>();
}

单元测试

在单元测试中,您可以使用null记录器——事实上,Logging中间件在核心抽象包中有一个NullLogger类正是出于这个原因。

或者,您可以将测试框架的输出方法封装到ILogger实现中并使用它,而无需修改代码。例如,xUnit为此使用ITestOutputHelper接口。您可以创建一个XUnitlogger,将调用转发到此接口:

public class XUnitLogger:ILogger
{
private readonly ITestOutputHelper _output;
public XUnitLogger(ITestOutputHelper output)
{
_output=output;
}
...
void Log(...)
{
_output.WriteLine(...);
}
}

相关内容

  • 没有找到相关文章

最新更新