我正在尝试使用依赖注入注入我自己的类,如下所示:
// 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 ......
答案 0 :(得分:3)
根据文档,您应该注意以下内容
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
方法通常要求的一些服务:
- 在构造函数中:
Startup
,IHostingEnvironment
- 使用
ILogger<Startup>
方法:ConfigureServices
- 在
IServiceCollection
方法中:Configure
,IApplicationBuilder
,IHostingEnvironment
ILoggerFactory
WebHostBuilder
方法添加的任何服务都可以 由ConfigureServices
类构造函数或其Startup
方法请求。 使用Configure
在WebHostBuilder
期间提供您需要的任何服务 方法
您正在尝试解析调用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();
}
}