Terminologi dari pertanyaan tidak benar-benar cocok dengan kode contoh. Ini Ambient Contextadalah pola yang digunakan untuk mengambil ketergantungan dari kelas mana saja di modul apa pun semudah mungkin, tanpa mencemari setiap kelas untuk menerima antarmuka ketergantungan, tetapi tetap mempertahankan gagasan inversi kontrol. Ketergantungan seperti itu biasanya didedikasikan untuk logging, keamanan, manajemen sesi, transaksi, caching, audit sehingga untuk masalah lintas sektoral dalam aplikasi itu. Ini entah bagaimana menjengkelkan untuk menambahkan ILogging, ISecurity, ITimeProvideruntuk konstruktor dan sebagian besar waktu tidak semua kelas perlu semua pada saat yang sama, jadi saya mengerti kebutuhan Anda.
Bagaimana jika masa pakai ISessioninstance berbeda dengan yang ILoggerada? Mungkin instance ISession harus dibuat pada setiap permintaan dan ILogger sekali. Jadi memiliki semua dependensi ini diatur oleh satu objek yang bukan wadah itu sendiri tidak terlihat pilihan yang tepat karena semua masalah ini dengan manajemen seumur hidup dan lokalisasi dan lainnya yang dijelaskan dalam utas ini.
Pertanyaan IAmbientContextdi atas tidak menyelesaikan masalah tidak mencemari setiap konstruktor. Anda masih harus menggunakannya dalam tanda tangan konstruktor, tentu saja, hanya sekali saja kali ini.
Jadi cara termudah BUKAN menggunakan injeksi konstruktor atau mekanisme injeksi lainnya untuk menangani dependensi lintas bidang, tetapi menggunakan panggilan statis . Kami sebenarnya melihat pola ini cukup sering, diimplementasikan oleh kerangka itu sendiri. Periksa Thread.CurrentPrincipal yang merupakan properti statis yang mengembalikan implementasi IPrincipalantarmuka. Ini juga dapat diatur sehingga Anda dapat mengubah implementasinya jika Anda suka, sehingga Anda tidak dapat menggunakannya.
MyCore terlihat seperti sekarang
public class MyCoreClass
{
public void BusinessFeature(string data)
{
LoggerContext.Current.Log(data);
_repository.SaveProcessedData();
SessionContext.Current.SetData(data);
...etc
}
}
Pola ini dan kemungkinan implementasi telah dijelaskan secara rinci oleh Mark Seemann dalam artikel ini . Mungkin ada implementasi yang bergantung pada wadah IoC sendiri yang Anda gunakan.
Anda ingin menghindari AmbientContext.Current.Logger, AmbientContext.Current.Sessionuntuk alasan yang sama seperti yang dijelaskan di atas.
Tetapi Anda memiliki opsi lain untuk menyelesaikan masalah ini: gunakan dekorator, intersepsi dinamis jika wadah Anda memiliki kemampuan ini atau AOP. Ambient Context harus menjadi pilihan terakhir karena kliennya menyembunyikan ketergantungan mereka melaluinya. Saya masih akan menggunakan Ambient Context jika antarmuka itu benar-benar meniru dorongan saya untuk menggunakan dependensi statis seperti DateTime.Nowatau ConfigurationManager.AppSettingsdan kebutuhan ini meningkat cukup sering. Tetapi pada akhirnya injeksi konstruktor mungkin bukan ide yang buruk untuk mendapatkan dependensi di mana-mana.
IServicedigunakan untuk berkomunikasi dengan layanan lain?" JikaIServicemewakili ketergantungan samar pada layanan lain maka itu terdengar seperti pencari lokasi dan seharusnya tidak ada. Kelas Anda harus bergantung pada antarmuka yang secara eksplisit menggambarkan apa yang akan dilakukan konsumen dengan mereka. Tidak ada kelas yang membutuhkan layanan untuk menyediakan akses ke layanan. Kelas membutuhkan ketergantungan yang melakukan sesuatu yang spesifik yang dibutuhkan kelas.