IServiceCollectionInterfejs służy do budowy kontenera wtrysku zależność. Po pełnym skompilowaniu kompiluje się do IServiceProviderinstancji, której można użyć do rozwiązania usług. Możesz wstrzyknąć IServiceProviderdo dowolnej klasy. Te IApplicationBuilderi HttpContextklasy mogą zapewnić usługodawcy, jak również, za pośrednictwem swoich ApplicationServiceslub RequestServiceswłaściwości odpowiednio.
IServiceProviderdefiniuje GetService(Type type)metodę rozwiązania usługi:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Dostępnych jest również kilka metod rozszerzania wygody, takich jak serviceProvider.GetService<IFooService>()(dodaj usingza Microsoft.Extensions.DependencyInjection).
Rozwiązywanie usług w klasie startowej
Wstrzykiwanie zależności
Hosting usługodawca środowisko wykonawcze mogą wprowadzić pewne usługi do konstruktora Startupklasy, takie jak IConfiguration,
IWebHostEnvironment( IHostingEnvironmentw wersji pre-3.0), ILoggerFactoryi IServiceProvider. Pamiętaj, że ten ostatni jest instancją zbudowaną przez warstwę hostingu i zawiera tylko niezbędne usługi do uruchomienia aplikacji .
Ta ConfigureServices()metoda nie zezwala na wstrzykiwanie usług, przyjmuje tylko IServiceCollectionargument. Ma to sens, ponieważ ConfigureServices()rejestrujesz usługi wymagane przez aplikację. Można tu jednak skorzystać z usług wprowadzonych do konstruktora startupu, na przykład:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Wszelkie zarejestrowane usługi ConfigureServices()można następnie wprowadzić do Configure()metody; możesz dodać dowolną liczbę usług po IApplicationBuilderparametrze:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Ręczne rozwiązywanie zależności
Jeśli trzeba ręcznie usług postanowienie, należy najlepiej użyć ApplicationServicesświadczone przez IApplicationBuilderw Configure()metodzie:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Możliwe jest przekazanie i bezpośrednie użycie IServiceProviderkonstruktora Startupklasy, ale jak wyżej, będzie on zawierał ograniczony podzbiór usług , a zatem ma ograniczoną użyteczność:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Jeśli musisz rozwiązać usługi w ConfigureServices()metodzie, wymagane jest inne podejście. Możesz zbudować półprodukt IServiceProviderz IServiceCollectioninstancji, która zawiera usługi zarejestrowane do tego momentu :
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>();
}
Uwaga:
Zasadniczo należy unikać rozwiązywania usług w ramach ConfigureServices()metody, ponieważ w rzeczywistości jest to miejsce, w którym konfigurujesz usługi aplikacji. Czasami potrzebujesz tylko dostępu do IOptions<MyOptions>instancji. Możesz to zrobić, wiążąc wartości z IConfigurationinstancji z instancją MyOptions(co jest zasadniczo tym, co robi struktura opcji):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Usługi ręcznego rozwiązywania problemów (zwane też lokalizatorem usług) są ogólnie uważane za anty-wzór . Chociaż ma swoje przypadki użycia (dla frameworków i / lub warstw infrastruktury), powinieneś unikać go w jak największym stopniu.