Các IServiceCollection
giao 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 IServiceProvider
thể 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 IServiceProvider
vào bất kỳ lớp học. Các lớp IApplicationBuilder
và HttpContext
cũng có thể cung cấp nhà cung cấp dịch vụ, thông qua các thuộc tính ApplicationServices
hoặc RequestServices
thuộ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 using
cho 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 Startup
lớp, chẳng hạn như IConfiguration
,
IWebHostEnvironment
( IHostingEnvironment
trong các phiên bản trước 3.0) ILoggerFactory
và 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 IServiceCollection
cuộ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 IApplicationBuilder
tham 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 IApplicationBuilder
trong 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 IServiceProvider
hàm tạo trong Startup
lớ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 IServiceProvider
từ IServiceCollection
trườ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ừ IConfiguration
thể 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.