使用ASP.NET Core DI解决实例
如何使用ASP.NET Core MVC内置dependency injection框架手动parsingtypes?
设置容器很简单:
public void ConfigureServices(IServiceCollection services) { // ... services.AddTransient<ISomeService, SomeConcreteService>(); }
但是,如何解决ISomeService
而不执行注入? 例如,我想要这样做:
ISomeService service = services.Resolve<ISomeService>();
IServiceCollection
中没有这样的方法。
Startup
类有几个选项。
注入依赖关系
运行时可以在Startup
类的构造函数中注入运行时服务,如IHostingEnvironment
和IServiceProvider
。
服务也可以在Configure()
方法中注入。 您可以在IApplicationBuilder
参数之后添加任意数量的参数。 您也可以在这里注入您在ConfigureServices()
方法中注册的自己的服务。 然而, ConfigureServices()
方法不允许注入服务,它只接受一个IServiceCollection
参数。
手动解决依赖关系
如果要手动parsing服务,可以让运行时在构造函数和Configure()
方法中注入一个IServiceProvider
实例:
public Startup(IServiceProvider serviceProvider) { var hostingEnv = serviceProvider.GetService<IHostingEnvironment>(); }
要么
public void Configure(IApplicationBuilder app, IServiceProvider serviceProvider) { var hostingEnv = serviceProvider.GetService<IHostingEnvironment>(); }
但是,如果您需要在ConfigureServices()
方法中parsing服务,则需要使用不同的方法。 您可以从IServiceCollection
实例构build一个中间的IServiceProvider
,其中包含在此之前注册的服务:
public void ConfigureService(IServiceCollection services) { services.AddSingleton<ISomeService, SomeService>(); // Build the intermediate service provider var sp = services.BuildServiceProvider(); var service = sp.GetService<ISomeService>(); }
你需要这个Microsoft.Extensions.DependencyInjection
包。
手动parsing实例涉及使用IServiceProvider
接口:
解决Startup.ConfigureServices中的依赖关系
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IMyService, MyService>(); var serviceProvider = services.BuildServiceProvider(); var service = serviceProvider.GetService<IMyService>(); }
解决Startup.Configure中的依赖关系
public void Configure( IApplicationBuilder application, IServiceProvider serviceProvider) { // By type. var service1 = (MyService)serviceProvider.GetService(typeof(MyService)); // Using extension method. var service2 = serviceProvider.GetService<MyService>(); // ... }
使用运行时注入服务
有些types可以作为方法参数注入:
public class Startup { public Startup( IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) { } public void ConfigureServices( IServiceCollection services) { } public void Configure( IApplicationBuilder application, IHostingEnvironment hostingEnvironment, IServiceProvider serviceProvider, ILoggerFactory loggerfactory, IApplicationLifetime applicationLifetime) { } }
如果你用一个模板生成一个应用程序,你将在Startup
类中有这样的东西:
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); }
然后可以在其中添加依赖关系,例如:
services.AddTransient<ITestService, TestService>();
如果你想访问你的控制器上的ITestService
,你可以在构造函数中添加IServiceProvider
,并且将被注入:
public HomeController(IServiceProvider serviceProvider)
然后你可以解决你添加的服务:
var service = serviceProvider.GetService<ITestService>();
请注意,要使用通用版本,您必须在命名空间中包含扩展名:
using Microsoft.Extensions.DependencyInjection;
ITestService.cs
public interface ITestService { int GenerateRandom(); }
TestService.cs
public class TestService : ITestService { public int GenerateRandom() { return 4; } }
Startup.cs(ConfigureServices)
public void ConfigureServices(IServiceCollection services) { services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); services.AddTransient<ITestService, TestService>(); }
HomeController.cs
using Microsoft.Extensions.DependencyInjection; namespace Core.Controllers { public class HomeController : Controller { public HomeController(IServiceProvider serviceProvider) { var service = serviceProvider.GetService<ITestService>(); int rnd = service.GenerateRandom(); }