IServiceCollectionІнтерфейс використовується для побудови контейнера ін'єкції залежностей. Після того, як він повністю побудований, він складається в IServiceProviderекземпляр, який ви можете використовувати для вирішення служб. Ви можете ввести IServiceProviderв будь-який клас. Ці IApplicationBuilderта HttpContextкласи можуть надати постачальник послуг , а також, з допомогою їх ApplicationServicesабо RequestServicesвластивостей , відповідно.
IServiceProviderвизначає GetService(Type type)спосіб вирішення послуги:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Існує також кілька методів розширення зручності, наприклад serviceProvider.GetService<IFooService>()(додати usingдля Microsoft.Extensions.DependencyInjection).
Вирішення послуг всередині класу запуску
Ін'єкційні залежності
Хостинг провайдер середовища виконання може вводити певні послуги в конструктор Startupкласу, таких як IConfiguration,
IWebHostEnvironment( IHostingEnvironmentу версії до 3.0), ILoggerFactoryі IServiceProvider. Зауважте, що останній - це екземпляр, побудований хостинг-шаром і містить лише необхідні сервіси для запуску програми .
ConfigureServices()Метод не дозволяє ін'єкційним послуги, вона тільки приймає IServiceCollectionаргумент. Це має сенс, оскільки ConfigureServices()ви реєструєте послуги, необхідні вашою заявкою. Однак ви можете використовувати послуги, введені в конструктор запуску, наприклад:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Будь-які сервіси, зареєстровані в, ConfigureServices()можуть бути введені в Configure()метод; після IApplicationBuilderпараметра можна додати довільну кількість послуг :
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Розв’язування залежностей вручну
Якщо вам потрібно вручну послуги рішучості, ви повинні переважно використовувати ApplicationServicesпередбачено IApplicationBuilderв Configure()методі:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Можна передати та безпосередньо використати IServiceProviderв конструкторі вашого Startupкласу, але, як зазначено вище, він буде містити обмежений підмножина сервісів і, таким чином, має обмежену корисність:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Якщо ви повинні вирішити послуги ConfigureServices()методом, потрібен інший підхід. Ви можете створити проміжний IServiceProviderз IServiceCollectionекземпляра, який містить послуги, зареєстровані до цього моменту :
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>();
}
Зверніть увагу: як
правило, ви повинні уникати вирішення служб всередині ConfigureServices()методу, оскільки це фактично місце, де ви налаштовуєте служби додатків. Іноді просто потрібен доступ до IOptions<MyOptions>екземпляра. Ви можете досягти цього, прив’язавши значення від IConfigurationекземпляра до екземпляра MyOptions(що по суті є тим, що робить рамка параметрів):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Служби, що вирішуються вручну (він же є "Локатор послуг", як правило, вважається анти-закономірністю . Хоча у нього є випадки використання (для фреймворків та / або інфраструктурних шарів), вам слід максимально уникати цього.