无法在 .NET Core 2.0 的启动构造函数中注入我自己的对象
Cannot inject my own objects in Startup constructor in .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");
}
在运行时,我收到以下错误:
Unhandled Exception: System.InvalidOperationException: Unable to
resolve service for type 'mtss.ws.IMainController' while attempting to
activate 'mtss.ws.Startup'. at
Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider
provider) at
Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider
provider, Type instanceType, Object[] parameters)
我想在 MainController 中注入一个 ILoggerFactory(就像在 Startup 中所做的那样),然后在 Startup 中注入一个新创建的 MainController...
你的设置是不可能的。 Startup
的构造函数将 运行 在你的 ConfigureServices
方法之前,这意味着你试图在你注册它之前注入 IMainController
依赖注入。
我假设你正在构建一个 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>();
}
我的服务
public interface IMyService
{
void DoSomethingPLEASE();
}
public class MyService : IMyService
{
public void DoSomethingPLEASE()
{
// Do Something PLEASE, ANYTHING!
}
}
家庭控制器
public class HomeController : Controller
{
public HomeController(ILoggerFactory loggerFactory, IMyService myServce)
{
myServce.DoSomethingPLEASE();
}
public IActionResult Index()
{
return View();
}
}
根据文档,您应该注意以下几点
ASP.NET Core dependency injection provides services during an
application's startup. You can request these services by including the
appropriate interface as a parameter on your Startup class's
constructor or its Configure method. The ConfigureServices
method
only takes an IServiceCollection
parameter (but any registered
service can be retrieved from this collection, so additional
parameters are not necessary).
Below are some of the services typically requested by Startup
methods:
- In the constructor:
IHostingEnvironment
, ILogger<Startup>
- In the
ConfigureServices
method: IServiceCollection
- In the
Configure
method: IApplicationBuilder
, IHostingEnvironment
,
ILoggerFactory
Any services added by the WebHostBuilder
ConfigureServices
method may
be requested by the Startup
class constructor or its Configure
method.
Use WebHostBuilder
to provide any services you need during Startup
methods.
您正在尝试解析调用 Startup
的构造函数时不可用的服务。 IMainController
在调用构造函数时尚未注册。但是,它应该在 Configure
被调用时可用,允许注入您的自定义服务,因为它是在 ConfigureServices
之后调用的,并且从 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
}
}
以上应该适用于 .net-core 2.0
除了@nkosi 在 的回答,您还可以使用 WebHostBuilder ConfigureServices 方法添加依赖项,如文档中所述:
Any services added by the WebHostBuilder ConfigureServices method may
be requested by the Startup class constructor or its Configure method.
Use WebHostBuilder to provide any services you need during Startup
methods.
会是这样的
// ...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 帮助我弄明白了,它有很多有用的例子
我正在尝试使用依赖项注入来注入我自己的 类,如下所示:
// 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");
}
在运行时,我收到以下错误:
Unhandled Exception: System.InvalidOperationException: Unable to resolve service for type 'mtss.ws.IMainController' while attempting to activate 'mtss.ws.Startup'. at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
我想在 MainController 中注入一个 ILoggerFactory(就像在 Startup 中所做的那样),然后在 Startup 中注入一个新创建的 MainController...
你的设置是不可能的。 Startup
的构造函数将 运行 在你的 ConfigureServices
方法之前,这意味着你试图在你注册它之前注入 IMainController
依赖注入。
我假设你正在构建一个 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>();
}
我的服务
public interface IMyService
{
void DoSomethingPLEASE();
}
public class MyService : IMyService
{
public void DoSomethingPLEASE()
{
// Do Something PLEASE, ANYTHING!
}
}
家庭控制器
public class HomeController : Controller
{
public HomeController(ILoggerFactory loggerFactory, IMyService myServce)
{
myServce.DoSomethingPLEASE();
}
public IActionResult Index()
{
return View();
}
}
根据文档,您应该注意以下几点
ASP.NET Core dependency injection provides services during an application's startup. You can request these services by including the appropriate interface as a parameter on your Startup class's constructor or its Configure method. The
ConfigureServices
method only takes anIServiceCollection
parameter (but any registered service can be retrieved from this collection, so additional parameters are not necessary).Below are some of the services typically requested by
Startup
methods:
- In the constructor:
IHostingEnvironment
,ILogger<Startup>
- In the
ConfigureServices
method:IServiceCollection
- In the
Configure
method:IApplicationBuilder
,IHostingEnvironment
,ILoggerFactory
Any services added by the
WebHostBuilder
ConfigureServices
method may be requested by theStartup
class constructor or itsConfigure
method. UseWebHostBuilder
to provide any services you need duringStartup
methods.
您正在尝试解析调用 Startup
的构造函数时不可用的服务。 IMainController
在调用构造函数时尚未注册。但是,它应该在 Configure
被调用时可用,允许注入您的自定义服务,因为它是在 ConfigureServices
之后调用的,并且从 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
}
}
以上应该适用于 .net-core 2.0
除了@nkosi 在
Any services added by the WebHostBuilder ConfigureServices method may be requested by the Startup class constructor or its Configure method. Use WebHostBuilder to provide any services you need during Startup methods.
会是这样的
// ...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 帮助我弄明白了,它有很多有用的例子