Các IServiceCollectiongiao diện được sử dụng để xây dựng một container dependency injection. Sau khi được xây dựng hoàn chỉnh, nó được soạn thành một IServiceProviderthể hiện mà bạn có thể sử dụng để giải quyết các dịch vụ. Bạn có thể tiêm một IServiceProvidervào bất kỳ lớp học. Các lớp IApplicationBuildervà HttpContextcũng có thể cung cấp nhà cung cấp dịch vụ, thông qua các thuộc tính ApplicationServiceshoặc RequestServicesthuộc tính của chúng.
IServiceProviderđịnh nghĩa một GetService(Type type)phương thức để giải quyết một dịch vụ:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Ngoài ra còn có một số phương thức mở rộng tiện lợi có sẵn, chẳng hạn như serviceProvider.GetService<IFooService>()(thêm một usingcho Microsoft.Extensions.DependencyInjection).
Giải quyết các dịch vụ bên trong lớp khởi động
Tiêm phụ thuộc
Nhà cung cấp dịch vụ lưu trữ của bộ thực thi có thể đưa một số dịch vụ nhất định vào hàm tạo của Startuplớp, chẳng hạn như IConfiguration,
IWebHostEnvironment( IHostingEnvironmenttrong các phiên bản trước 3.0) ILoggerFactoryvà IServiceProvider. Lưu ý rằng cái sau là một thể hiện được tạo bởi lớp lưu trữ và chỉ chứa các dịch vụ thiết yếu để khởi động một ứng dụng .
Các ConfigureServices()phương pháp không cho phép các dịch vụ tiêm, nó chỉ chấp nhận một IServiceCollectioncuộc tranh cãi. Điều này có ý nghĩa bởi vì đó ConfigureServices()là nơi bạn đăng ký các dịch vụ theo yêu cầu của ứng dụng của bạn. Tuy nhiên, bạn có thể sử dụng các dịch vụ được chèn trong hàm tạo của phần khởi động tại đây, ví dụ:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Bất kỳ dịch vụ nào được đăng ký ConfigureServices()sau đó đều có thể được đưa vào Configure()phương thức; bạn có thể thêm một số lượng dịch vụ tùy ý sau IApplicationBuildertham số:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Giải quyết phụ thuộc thủ công
Nếu bạn cần giải quyết thủ công các dịch vụ, tốt nhất bạn nên sử dụng ApplicationServicesđược cung cấp bởi IApplicationBuildertrong Configure()phương thức:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Có thể vượt qua và sử dụng trực tiếp một IServiceProviderhàm tạo trong Startuplớp của bạn , nhưng như trên, điều này sẽ chứa một tập hợp con các dịch vụ hạn chế và do đó có tiện ích hạn chế:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Nếu bạn phải giải quyết các dịch vụ trong ConfigureServices()phương thức, một cách tiếp cận khác là bắt buộc. Bạn có thể xây dựng một trung gian IServiceProvidertừ IServiceCollectiontrường hợp có chứa các dịch vụ đã được đăng ký cho đến thời điểm đó :
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IFooService, FooService>();
// Build the intermediate service provider
var sp = services.BuildServiceProvider();
// This will succeed.
var fooService = sp.GetService<IFooService>();
// This will fail (return null), as IBarService hasn't been registered yet.
var barService = sp.GetService<IBarService>();
}
Xin lưu ý:
Nói chung, bạn nên tránh giải quyết các dịch vụ bên trong ConfigureServices()phương thức, vì đây thực sự là nơi bạn định cấu hình các dịch vụ ứng dụng. Đôi khi bạn chỉ cần truy cập vào một IOptions<MyOptions>ví dụ. Bạn có thể thực hiện điều này bằng cách ràng buộc các giá trị từ IConfigurationthể hiện với một thể hiện của MyOptions(về cơ bản là những gì khung tùy chọn thực hiện):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Các dịch vụ phân giải thủ công (còn gọi là Bộ định vị dịch vụ) thường được coi là một mẫu chống . Mặc dù nó có các trường hợp sử dụng (đối với khung và / hoặc các lớp cơ sở hạ tầng), bạn nên tránh nó càng nhiều càng tốt.