The IServiceCollection
antarmuka digunakan untuk membangun wadah injeksi ketergantungan. Setelah sepenuhnya dibangun, itu akan dikomposisikan ke sebuah IServiceProvider
instance yang dapat Anda gunakan untuk menyelesaikan layanan. Anda dapat menyuntikkan IServiceProvider
ke dalam kelas apa pun. The IApplicationBuilder
dan HttpContext
kelas dapat memberikan penyedia layanan juga, melalui mereka ApplicationServices
atauRequestServices
sifat masing-masing.
IServiceProvider
mendefinisikan GetService(Type type)
metode untuk menyelesaikan layanan:
var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
Ada juga beberapa metode ekstensi kenyamanan yang tersedia, seperti serviceProvider.GetService<IFooService>()
(tambahkan using
untuk Microsoft.Extensions.DependencyInjection
).
Menyelesaikan layanan di dalam kelas startup
Dependensi menyuntikkan
Penyedia layanan hosting runtime dapat menyuntikkan layanan tertentu ke konstruktor Startup
kelas, seperti IConfiguration
,
IWebHostEnvironment
( IHostingEnvironment
dalam versi pra-3.0), ILoggerFactory
dan IServiceProvider
. Perhatikan bahwa yang terakhir adalah contoh yang dibangun oleh lapisan hosting dan hanya berisi layanan penting untuk memulai aplikasi .
The ConfigureServices()
Metode tidak memungkinkan layanan suntik, hanya menerima sebuah IServiceCollection
argumen. Ini masuk akal karena di ConfigureServices()
situlah Anda mendaftarkan layanan yang diperlukan oleh aplikasi Anda. Namun Anda dapat menggunakan layanan yang disuntikkan di konstruktor startup di sini, misalnya:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Use Configuration here
}
Setiap layanan yang terdaftar di ConfigureServices()
kemudian dapat disuntikkan ke dalam Configure()
metode; Anda dapat menambahkan sejumlah layanan sewenang-wenang setelah IApplicationBuilder
parameter:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IFooService>();
}
public void Configure(IApplicationBuilder app, IFooService fooService)
{
fooService.Bar();
}
Mengatasi dependensi secara manual
Jika Anda perlu menyelesaikan layanan secara manual, Anda sebaiknya menggunakan yang ApplicationServices
disediakan oleh IApplicationBuilder
dalam Configure()
metode:
public void Configure(IApplicationBuilder app)
{
var serviceProvider = app.ApplicationServices;
var hostingEnv = serviceProvider.GetService<IHostingEnvironment>();
}
Dimungkinkan untuk lulus dan secara langsung menggunakan nilai IServiceProvider
dalam konstruktor Startup
kelas Anda , tetapi seperti di atas ini akan berisi subset layanan yang terbatas , dan dengan demikian memiliki utilitas terbatas:
public Startup(IServiceProvider serviceProvider)
{
var hostingEnv = serviceProvider.GetService<IWebHostEnvironment>();
}
Jika Anda harus menyelesaikan layanan dalam ConfigureServices()
metode ini, diperlukan pendekatan yang berbeda. Anda dapat membangun perantara IServiceProvider
dari IServiceCollection
instance yang berisi layanan yang telah terdaftar hingga saat itu :
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>();
}
Harap dicatat:
Secara umum Anda harus menghindari menyelesaikan layanan di dalam ConfigureServices()
metode, karena ini sebenarnya adalah tempat di mana Anda mengkonfigurasi layanan aplikasi. Terkadang Anda hanya perlu akses ke sebuah IOptions<MyOptions>
instance. Anda bisa mencapai ini dengan mengikat nilai-nilai dari IConfiguration
instance ke instance MyOptions
(yang pada dasarnya adalah apa yang dilakukan kerangka kerja opsi):
public void ConfigureServices(IServiceCollection services)
{
var myOptions = new MyOptions();
Configuration.GetSection("SomeSection").Bind(myOptions);
}
Layanan penyelesaian secara manual (alias Service Locator) umumnya dianggap sebagai anti-pola . Meskipun memiliki kasus penggunaannya (untuk kerangka kerja dan / atau lapisan infrastruktur), Anda harus menghindarinya sebanyak mungkin.