无法在.NET Core 2.0的启动构造函数中注入我自己的对象

ope*_*sas 4 c# dependency-injection .net-core asp.net-core .net-core-2.0

我正在尝试使用依赖项注入来注入自己的类,如下所示:

// Startup.cs
public class Startup
{
    private readonly ILogger _log;
    private readonly IMainController _controller;
    public Startup(ILoggerFactory loggerFactory, IMainController controller)
    {
        _log = loggerFactory.CreateLogger("Logger");
        _controller = controller;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IMainController, MainController>();
        // services.AddTransient<MainController, MainController>();
    }
Run Code Online (Sandbox Code Playgroud)

然后是MainController,要注入的对象

// MainController.cs
public interface IMainController
{
    Task Run(HttpContext context);
}
public class MainController : IMainController
{
    private readonly ILogger _log;

    public MainController(ILoggerFactory loggerFactory)
    {
        _log = loggerFactory.CreateLogger("Logger");
    }
Run Code Online (Sandbox Code Playgroud)

在运行时,出现以下错误:

未处理的异常:System.InvalidOperationException:尝试激活“ mtss.ws.Startup”时,无法解析“ mtss.ws.IMainController”类型的服务。在Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider提供者),在Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider提供者,类型instanceType,Object []参数)

我想在MainController中注入一个ILoggerFactory(就像在Startup中一样),然后在Startup中注入一个新创建的MainController ...

Nko*_*osi 5

根据文档,您应该注意以下几点

启动时可用的服务

ASP.NET Core 依赖项注入在应用程序启动期间提供服务。您可以通过在 Startup 类的构造函数或其 Configure 方法中包含适当的接口作为参数来请求这些服务。该ConfigureServices方法只接受一个IServiceCollection参数(但可以从该集合中检索任何已注册的服务,因此不需要额外的参数)。

以下是Startup方法通常请求的一些服务:

  • 在构造函数中:IHostingEnvironmentILogger<Startup>
  • ConfigureServices方法中:IServiceCollection
  • Configure方法中:IApplicationBuilder, IHostingEnvironment, ILoggerFactory

由该WebHostBuilder ConfigureServices方法添加的任何服务都可以由Startup类构造函数或其Configure方法请求。用于WebHostBuilderStartup 方法期间提供您需要的任何服务。

您正在尝试解决Startup调用构造函数时不可用的服务。IMainController调用构造函数时尚未注册。但是,它应该在Configure被调用时可用,允许有机会注入您的自定义服务,因为它是在ConfigureServicesRTM之后调用的,并且从 RTM 开始,将为该Configure方法创建一个范围服务提供者。

// Startup.cs
public class Startup {
    private ILogger _log;
    private IMainController _controller;

    public Startup() {

    }

    public void ConfigureServices(IServiceCollection services) {
        services.AddScoped<IMainController, MainController>();
        // services.AddTransient<MainController, MainController>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
               ILoggerFactory loggerFactory, IMainController controller) {
        _log = loggerFactory.CreateLogger("Logger");
        _controller = controller;
        //...other code removed for brevity
    }
}
Run Code Online (Sandbox Code Playgroud)

以上应该适用于 .net-core 2.0


ope*_*sas 5

除了/sf/answers/3220925711/上的 @nkosi答案,您还可以使用WebHostBuilder ConfigureServices方法添加依赖项,如文档中所述:

由WebHostBuilder ConfigureServices方法添加的任何服务都可以由Startup类构造函数或其Configure方法请求。使用WebHostBuilder可以在启动方法期间提供所需的任何服务。

就像这样

// ...other code removed for brevity
// in Program.cs
public static void Main(string[] args)
{
    BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureServices(services =>
            services.AddScoped<IMainController, MainController>()
        )
        .UseStartup<Startup>()
        .Build();
Run Code Online (Sandbox Code Playgroud)

然后在Startup.cs中,我可以执行以下操作

private readonly ILogger _log;
private readonly IMainController _controller;

public Startup(ILoggerFactory loggerFactory, IMainController controller)
{
    _log = loggerFactory.CreateLogger("Logger");
    _controller = controller;
}
Run Code Online (Sandbox Code Playgroud)

要点帮我弄清楚,它得到了有用的例子很多的