Die IServiceCollectionSchnittstelle wird zum Erstellen eines Abhängigkeitsinjektionscontainers verwendet. Nachdem es vollständig erstellt wurde, wird es zu einer IServiceProviderInstanz zusammengesetzt, mit der Sie Dienste auflösen können. Sie können eine IServiceProviderin jede Klasse injizieren . Die Klassen IApplicationBuilderund HttpContextkönnen den Dienstanbieter auch über ihre ApplicationServicesbzw. RequestServicesEigenschaften bereitstellen .
IServiceProviderdefiniert eine GetService(Type type)Methode zum Auflösen eines Dienstes:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Es stehen auch verschiedene praktische Erweiterungsmethoden zur Verfügung, z. B. serviceProvider.GetService<IFooService>()(ein usingfür hinzufügen Microsoft.Extensions.DependencyInjection).
Auflösen von Diensten innerhalb der Startklasse
Abhängigkeiten einfügen
Die Laufzeit der Hosting - Service - Provider können bestimmte Dienste in den Konstruktor der injizieren StartupKlasse, wie IConfiguration,
IWebHostEnvironment( IHostingEnvironmentin Pre-3.0 - Versionen), ILoggerFactoryund IServiceProvider. Beachten Sie, dass letztere eine von der Hosting-Schicht erstellte Instanz ist und nur die wesentlichen Dienste zum Starten einer Anwendung enthält .
Die ConfigureServices()Methode erlaubt kein Injizieren von Diensten, sondern akzeptiert nur ein IServiceCollectionArgument. Dies ist sinnvoll, da ConfigureServices()Sie hier die für Ihre Anwendung erforderlichen Dienste registrieren. Sie können hier jedoch Dienste verwenden, die in den Konstruktor des Startups eingefügt wurden, zum Beispiel:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Alle in registrierten Dienste ConfigureServices()können dann in die Configure()Methode eingefügt werden. Sie können nach dem IApplicationBuilderParameter eine beliebige Anzahl von Diensten hinzufügen :
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Abhängigkeiten manuell auflösen
Wenn Sie manuell lösen Dienste benötigen, sollten Sie vorzugsweise die Verwendung der ApplicationServicesvon einer IApplicationBuilderin dem Configure()Verfahren:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Es ist möglich, ein IServiceProviderim Konstruktor Ihrer StartupKlasse zu übergeben und direkt zu verwenden , aber wie oben enthält dieses eine begrenzte Teilmenge von Diensten und hat daher einen begrenzten Nutzen:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Wenn Sie Dienste in der ConfigureServices()Methode auflösen müssen , ist ein anderer Ansatz erforderlich. Sie können IServiceProvideraus der IServiceCollectionInstanz ein Zwischenprodukt erstellen, das die bis zu diesem Zeitpunkt registrierten Dienste enthält :
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>();
}
Bitte beachten Sie: Im
Allgemeinen sollten Sie das Auflösen von Diensten innerhalb der ConfigureServices()Methode vermeiden , da dies tatsächlich der Ort ist, an dem Sie die Anwendungsdienste konfigurieren . Manchmal benötigen Sie nur Zugriff auf eine IOptions<MyOptions>Instanz. Sie können dies erreichen, indem Sie die Werte von der IConfigurationInstanz an eine Instanz von binden MyOptions(was im Wesentlichen das Options-Framework tut):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Das manuelle Auflösen von Diensten (auch als Service Locator bezeichnet) wird im Allgemeinen als Anti-Pattern angesehen . Obwohl es Anwendungsfälle gibt (für Frameworks und / oder Infrastrukturschichten), sollten Sie dies so weit wie möglich vermeiden.