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);
}
Служби, що вирішуються вручну (він же є "Локатор послуг", як правило, вважається анти-закономірністю . Хоча у нього є випадки використання (для фреймворків та / або інфраструктурних шарів), вам слід максимально уникати цього.