L' IServiceCollection
interface est utilisée pour créer un conteneur d'injection de dépendances. Une fois entièrement construit, il se compose d'une IServiceProvider
instance que vous pouvez utiliser pour résoudre les services. Vous pouvez injecter un IServiceProvider
dans n'importe quelle classe. Les classes IApplicationBuilder
et HttpContext
peuvent également fournir le fournisseur de services, via leurs propriétés ApplicationServices
ou RequestServices
.
IServiceProvider
définit une GetService(Type type)
méthode pour résoudre un service:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Il existe également plusieurs méthodes d'extension pratiques, telles que serviceProvider.GetService<IFooService>()
(ajouter un using
pour Microsoft.Extensions.DependencyInjection
).
Résolution des services dans la classe de démarrage
Injection de dépendances
Le fournisseur de services d' hébergement de l'exécution peut injecter certains services dans le constructeur de la Startup
classe, par exemple IConfiguration
,
IWebHostEnvironment
( IHostingEnvironment
en version pré-3.0), ILoggerFactory
et IServiceProvider
. Notez que cette dernière est une instance construite par la couche d'hébergement et ne contient que les services essentiels pour démarrer une application .
La ConfigureServices()
méthode n'autorise pas l'injection de services, elle accepte uniquement un IServiceCollection
argument. Cela est logique car ConfigureServices()
c'est là que vous enregistrez les services requis par votre application. Cependant, vous pouvez utiliser ici les services injectés dans le constructeur du démarrage, par exemple:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Tous les services enregistrés dans ConfigureServices()
peuvent alors être injectés dans la Configure()
méthode; vous pouvez ajouter un nombre arbitraire de services après le IApplicationBuilder
paramètre:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Résolution manuelle des dépendances
Si vous devez résoudre manuellement des services, vous devez de préférence utiliser le ApplicationServices
fourni par IApplicationBuilder
dans la Configure()
méthode:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Il est possible de passer et d'utiliser directement un IServiceProvider
dans le constructeur de votre Startup
classe, mais comme ci - dessus, cela contiendra un sous-ensemble limité de services , et a donc une utilité limitée:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Si vous devez résoudre des services dans la ConfigureServices()
méthode, une approche différente est requise. Vous pouvez créer un intermédiaire à IServiceProvider
partir de l' IServiceCollection
instance qui contient les services qui ont été enregistrés jusqu'à ce point :
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>();
}
Remarque:
En règle générale, vous devez éviter de résoudre les services dans la ConfigureServices()
méthode, car c'est en fait l'endroit où vous configurez les services d'application. Parfois, vous avez juste besoin d'accéder à une IOptions<MyOptions>
instance. Vous pouvez accomplir cela en liant les valeurs de l' IConfiguration
instance à une instance de MyOptions
(ce qui est essentiellement ce que fait le cadre d'options):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Les services de résolution manuelle (aka Service Locator) sont généralement considérés comme un anti-modèle . Bien qu'il ait ses cas d'utilisation (pour les couches d'infrastructure et / ou d'infrastructure), vous devez l'éviter autant que possible.