Die IServiceCollection
Schnittstelle wird zum Erstellen eines Abhängigkeitsinjektionscontainers verwendet. Nachdem es vollständig erstellt wurde, wird es zu einer IServiceProvider
Instanz zusammengesetzt, mit der Sie Dienste auflösen können. Sie können eine IServiceProvider
in jede Klasse injizieren . Die Klassen IApplicationBuilder
und HttpContext
können den Dienstanbieter auch über ihre ApplicationServices
bzw. RequestServices
Eigenschaften bereitstellen .
IServiceProvider
definiert 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 using
fü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 Startup
Klasse, wie IConfiguration
,
IWebHostEnvironment
( IHostingEnvironment
in Pre-3.0 - Versionen), ILoggerFactory
und 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 IServiceCollection
Argument. 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 IApplicationBuilder
Parameter 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 ApplicationServices
von einer IApplicationBuilder
in dem Configure()
Verfahren:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Es ist möglich, ein IServiceProvider
im Konstruktor Ihrer Startup
Klasse 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 IServiceProvider
aus der IServiceCollection
Instanz 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 IConfiguration
Instanz 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.