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

时间:2017-09-02 06:35:51

标签: c# dependency-injection .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>();
    }

然后是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");
    }

在运行时,我收到以下错误:

  

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

我想在MainController中注入一个ILoggerFactory(正如它在Startup中所做的那样),然后在Startup中注入一个新创建的MainController ......

4 个答案:

答案 0 :(得分:3)

根据文档,您应该注意以下内容

  

Services Available in Startup

     

ASP.NET核心依赖注入提供服务   应用程序的启动。您可以通过加入来请求这些服务   适当的接口作为Startup类的参数   构造函数或其Configure方法。 public interface ISampleInterface { void Run(); } public class SampleClass : ISampleInterface { public Action Run { get; set; } void ISampleInterface.Run() { this.Run(); } } public class SomeClass { public void ActionRunner(ISampleInterface param) { param.Run(); } public void someFumction() { ActionRunner(new SampleClass { Run = () => { // Code goes here } }); } } 方法   只接受ConfigureServices参数(但任何已注册的参数)   可以从这个集合中检索服务,所以额外的   参数不是必需的。)

     

以下是IServiceCollection方法通常要求的一些服务:

     
      
  • 在构造函数中:StartupIHostingEnvironment
  •   
  • 使用ILogger<Startup>方法:ConfigureServices
  •   
  • IServiceCollection方法中:ConfigureIApplicationBuilder,   IHostingEnvironment
  •   
     

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

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

ConfigureServices

以上内容适用于.net-core 2.0

答案 1 :(得分:2)

您的设置无法进行。 Startup的构造函数将在ConfigureServices方法之前运行,这意味着您在注册依赖注入之前尝试注入IMainController

答案 2 :(得分:2)

除了https://stackoverflow.com/a/46013224/47633的@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();

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

private readonly ILogger _log;
private readonly IMainController _controller;

public Startup(ILoggerFactory loggerFactory, IMainController controller)
{
    _log = loggerFactory.CreateLogger("Logger");
    _controller = controller;
}

gist让我弄明白了,它有很多有用的例子

答案 3 :(得分:0)

我假设您正在构建一个ASP.Net Core2.0 MVC应用程序(但您的MainController不会从Controller继承,因此我对此持怀疑态度)您不需要在DI容器中注册您的控制器。您拥有的构造函数应足以让ASP.Net为您注入ILogger具体实例。

  

public MainController(ILoggerFactory loggerFactory)

如果您还想将自己的服务添加到控制器中,那么控制器构造函数将更改为: -

<强>控制器

public MainController(ILoggerFactory loggerFactory, IMyService myService)

您在Startup.cs中的服务注册可能如下所示: -

<强> Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddScoped<IMyService, MyService>();
}

<强>为MyService

public interface IMyService
{
    void DoSomethingPLEASE();
}
public class MyService : IMyService
{
    public void DoSomethingPLEASE()
    {
        // Do Something PLEASE, ANYTHING!
    }
}

<强>的HomeController

public class HomeController : Controller
{
    public HomeController(ILoggerFactory loggerFactory, IMyService myServce)
    {
        myServce.DoSomethingPLEASE();
    }
    public IActionResult Index()
    {
        return View();
    }
}