L' IServiceCollectioninterface est utilisée pour créer un conteneur d'injection de dépendances. Une fois entièrement construit, il se compose d'une IServiceProviderinstance que vous pouvez utiliser pour résoudre les services. Vous pouvez injecter un IServiceProviderdans n'importe quelle classe. Les classes IApplicationBuilderet HttpContextpeuvent également fournir le fournisseur de services, via leurs propriétés ApplicationServicesou RequestServices.
IServiceProviderdé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 usingpour 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 Startupclasse, par exemple IConfiguration,
IWebHostEnvironment( IHostingEnvironmenten version pré-3.0), ILoggerFactoryet 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 IServiceCollectionargument. 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 IApplicationBuilderparamè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 ApplicationServicesfourni par IApplicationBuilderdans 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 IServiceProviderdans le constructeur de votre Startupclasse, 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 à IServiceProviderpartir de l' IServiceCollectioninstance 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' IConfigurationinstance à 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.