我打算在多个项目中使用中间件库。中间件本身看起来像:
public SdkMiddleware(RequestDelegate next, ILogger<SdkMiddleware> logger, ISdk sdk)
{
this.next = next;
this.logger = logger;
this.sdk = agentSdk;
this.sdk.Init();
...
}
感谢DI,我可以简单地注入我的记录器:
// Would rather this class be internal...
public class Sdk: ISdk
{
private ILogger<Sdk> logger;
public Sdk(ILogger<Sdk> logger)
{
this.logger = logger;
}
public void Init() {
this.logger.Info(...) // Do some logging
}
这样做的缺点是我的课程需要在每个ASP.Net项目Startup.cs
中注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISdk, Sdk>();
是最佳/唯一的路线吗?每次我想将一个记录器注入一个类时,我需要在我的组合根目录中为DI注册该类吗?
答案 0 :(得分:2)
让库的使用者在合成根中构成此库的依赖项没有任何错误。这就是依赖注入的工作原理。您当然可以提供一些默认实现和自定义扩展方法,将这些默认实现注册到DI中,然后让消费者只需调用您的扩展方法。
答案 1 :(得分:1)
我觉得有些事情需要澄清:
为了理解依赖注入(DI)的好处,最好看一下DI实现的控制反转(IoT)原理。 在您的情况下,您希望SdkMiddleware类包含对ILogger实现的引用。最简单的方法是让SdkMiddleware类创建一个实现ILogger接口的类的实例。这种方法的缺点是SdkMiddleware需要知道哪个类实现ILogger接口以及如何实例化它。换句话说,SdkMiddleware可以控制ILogger对象的创建。当知道哪个类实现ILogger以及如何创建它的实例的责任从SdkMiddleware转移到其他类(DI中的依赖容器)和实例(如果它被赋予SdkMiddleware使用)时,就会发生控制反转在DI中注射)。在这种情况下,对ILogger对象的创建的控制在SdkMiddleware之外。由于这改变了控制方向,因此称为&#34;控制反转&#34;。 这种方法的好处是,当您需要提供ILogger的另一个实现或更改创建该类实例的方式时,您根本不需要更改SdkMiddleware。
现在我们澄清了为什么我们使用DI,让我们来看看我们实际使用它需要什么。 创建所有实例的对象,控制将哪个对象注入其中并放弃准备使用的对象通常称为DI容器或IoT容器。在asp.net核心&#34; IServiceCollection服务&#34;用作这样的容器。但它仍然需要知道如何创建对象以及注入哪个接口的实现。这是引导进入的地方。 在引导程序类或方法中,您需要指定如何从类构建对象以及类如何与接口相关。作为前者的示例,假设您需要将数据库的连接字符串从配置传递到创建数据库连接的类。至于后者,这正是你的行&#34; services.AddTransient()&#34;确实
很抱歉花了这么长时间才得到你问题的实际答案,但我想首先提供一些概述。 您是否需要指定类和接口之间的关系以将记录器注入您的类?不。你的类甚至可能没有开头的接口,如果你要求一个类的对象而不是一个接口的实例,DI容器将默认注入其中的所有依赖项。您还可以使用或定义一些约定优于配置解决方案,以便自动进行类和接口的绑定。 底线是没有连接类的注册和实际注入。但是您提供的代码是执行此操作的默认方式。