C# Startup类的Configure()方法中服务的方法注入或构造函数注入之间是否有区别?

C# Startup类的Configure()方法中服务的方法注入或构造函数注入之间是否有区别?,c#,asp.net-core,.net-core,startup,C#,Asp.net Core,.net Core,Startup,根据,我们可以将以下服务注入startup类: IWebHostEnvironment I外部环境 I配置 但我们也可以在Configure()方法中使用方法注入来解决这些服务: 可以在Configure方法签名中指定其他服务,例如IWebHostEnvironment、iLogger Factory或ConfigureServices中定义的任何内容。如果这些服务可用,则注入它们 我使用哪种注射变体有区别吗 具体来说,在构造函数中解析IWebHostEnvironment,然后通过私有字段

根据,我们可以将以下服务注入startup类:

  • IWebHostEnvironment
  • I外部环境
  • I配置
但我们也可以在
Configure()
方法中使用方法注入来解决这些服务:

可以在Configure方法签名中指定其他服务,例如IWebHostEnvironment、iLogger Factory或ConfigureServices中定义的任何内容。如果这些服务可用,则注入它们

我使用哪种注射变体有区别吗

具体来说,在构造函数中解析
IWebHostEnvironment
,然后通过私有字段在
Configure()
方法中访问它与将其作为方法参数注入有什么区别

public class Startup
{
    private readonly IWebHostEnvironment env;

    public Startup(IWebHostEnvironment env)
    {
        this.env = env;
    }

    public void Configure(IApplicationBuilder app)
    {
        if (this.env.IsDevelopment())
        [...]
    }
}
vs


一般来说,构造函数和方法DI可以是首选项,也可以是基于某个框架的需求,该框架使用此方法,而不是其他方法。在
asp.net core
(以及
.net core
一般情况下)中,建议使用构造函数注入,因为它清楚地说明了依赖关系。这比方法注入更有意义。但是,在某些情况下,您必须使用方法注入,因为依赖项只能在调用方法时可用,或者至少在构建类/服务时不可用。有时注入的服务仅用于特定的方法调用,在这种情况下,将使用方法注入。在某些情况下,服务实例是单例的,但其方法调用需要一些作用域服务,因此将使用方法注入。该场景的一个示例是使用基于约定的中间件时。基于约定的中间件是单例的,在应用程序启动时创建一次,而不是针对每个请求。因此,必须将所有作用域服务注入
Invoke
InvokeAsync
方法。但是,基于工厂的中间件可以将其作用域服务注入构造函数,因为它们可以根据请求创建(注册为作用域或瞬态)

启动
类的情况相同。您可以将一些内置服务注入到
启动
的构造函数中,例如
IConfiguration
IWebHostEnvironment
。。。通常,
ConfigureServices
之前的许多可用服务(在之前注册)可以注入到
启动
的构造函数中。这意味着在
ConfigureServices
中注册的所有服务都不可用于注入
启动
的构造函数。但是,您可以将所有已注册的服务(包括内置服务和您的服务)注入方法
Configure
。请注意,注入
Configure
的服务应该是单例和瞬态的,对于作用域服务,在使用它们时可能会出现问题。这实际上取决于您使用的特定服务

下面的示例显示,无法将您自己的服务(在
ConfigureServices
中注册)注入到
启动
的构造函数中:

 public interface ISomeService {}
 public class SomeService : ISomeService {}


 public class Startup {
      //will not work because at this time, the ISomeService has not been registered yet
      public Startup(ISomeService someService){
          //an error will be thrown complaining about not being able to 
          //resolve the ISomeService
      }

      public void ConfigureServices(IServiceCollection services){
          //...
          services.AddSingleton<ISomeService,SomeService>();
          //...
      }
      //this works because at this time the ConfigureServices was called
      //the services container has been built with your registered ISomeService
      public void Configure(IApplicationBuilder app, ISomeService someService){
          //...
      }
 }
公共接口服务{}
公共类SomeService:ISomeService{}
公营创业{
//将不起作用,因为此时该服务尚未注册
公共启动(ISomeService someService){
//将抛出一个错误,抱怨无法
//解决该服务的问题
}
public void配置服务(IServiceCollection服务){
//...
services.AddSingleton();
//...
}
//这是因为此时调用了ConfigureServices
//服务容器已使用您的注册服务生成
public void配置(IApplicationBuilder应用程序,ISomeService someService){
//...
}
}

我认为基本上,如果您需要在多个方法中使用服务,那么将其注入构造函数是有意义的。否则,注入方法。谢谢!因此,对于
IWebHostEnvironment
,这意味着它没有什么区别,因为它是一个单实例,因此在两种变体中解析为相同的实例。@Sandro是的,没有区别。
 public interface ISomeService {}
 public class SomeService : ISomeService {}


 public class Startup {
      //will not work because at this time, the ISomeService has not been registered yet
      public Startup(ISomeService someService){
          //an error will be thrown complaining about not being able to 
          //resolve the ISomeService
      }

      public void ConfigureServices(IServiceCollection services){
          //...
          services.AddSingleton<ISomeService,SomeService>();
          //...
      }
      //this works because at this time the ConfigureServices was called
      //the services container has been built with your registered ISomeService
      public void Configure(IApplicationBuilder app, ISomeService someService){
          //...
      }
 }