Saya cukup nyaman dengan injeksi ketergantungan menggunakan NInject di MVC3. Saat bekerja di aplikasi MVC3, saya mengembangkan Pabrik Pembuatan Pengendali kustom menggunakan NInject, sehingga setiap pengontrol yang dibuat akan memiliki ketergantungan yang disuntikkan di dalamnya melalui Pabrik Pengendali ini.
Sekarang saya mulai mengembangkan aplikasi windows, saya ingin menggunakan Aplikasi Dependency Injection yang luas. yaitu Setiap objek harus dibuat melalui NInject, sehingga memudahkan Unit Testing. Tolong bimbing saya untuk memastikan bahwa setiap objek yang dibuat harus melalui Pabrik NInject saja.
Sebagai contoh, jika pada bentuk windows apa pun pada Button_Click
acara saya menulis:
TestClass testClass = new TestClass()
dan TestClass
memiliki ketergantungan pada, katakanlah, ITest
maka itu harus diselesaikan secara otomatis. Saya tahu saya bisa menggunakan:
Ikernel kernel = new StandardKenel()
//AddBinding()
TestClass testClass = kenel.get<TestClass>();
Tetapi saya merasa membosankan untuk melakukan ini setiap kali saya ingin membuat objek. Ini juga memaksa pengembang untuk membuat objek dengan cara tertentu. Bisakah itu dibuat lebih baik?
Bisakah saya memiliki repositori pusat untuk pembuatan objek dan kemudian setiap pembuatan objek akan secara otomatis menggunakan repositori itu?
sumber
Jawaban:
Untuk aplikasi klien, seringkali yang terbaik adalah mengadaptasi pola seperti MVP (atau MVVM) dan menggunakan data-binding dari formulir ke ViewModel atau Presenter yang mendasarinya.
Untuk ViewModels, Anda dapat menyuntikkan dependensi yang diperlukan menggunakan Injeksi Konstruktor standar.
Dalam Komposisi Root aplikasi Anda, Anda dapat memasang seluruh grafik objek untuk aplikasi Anda. Anda tidak perlu menggunakan DI Container (seperti Ninject) untuk ini, tetapi Anda bisa.
sumber
Aplikasi Windows Forms biasanya memiliki titik masuk yang terlihat seperti ini:
Jika Anda menyatakan hal ini dalam kode root komposisi Anda, Anda dapat sangat mengurangi jumlah tempat di mana Anda memiliki kode yang secara eksplisit memanggil Ninject seolah-olah itu adalah Pencari Layanan.
Dari titik ini, Anda menyuntikkan semua dependensi Anda melalui injeksi konstruktor.
Jika "ketergantungan" Anda adalah sesuatu yang Anda harus dapat hasilkan berkali-kali, maka yang benar-benar Anda butuhkan adalah pabrik:
Anda dapat mengimplementasikan antarmuka IFactory dengan cara ini untuk menghindari keharusan membuat satu ton implementasi satu kali:
sumber
InjectionFactory<T>
implementasikan, maka kode yang disediakan harus bekerja dengan baik. Apakah ada sesuatu yang Anda alami masalah?Type
, tetapi yang akan menjamin bahwa objek yang terhidrasi untukType
penerapan itu atau memperluas jenis generik yang diberikan. Tidak ada yang terlalu istimewa.Saya selalu menulis bungkus Adaptor untuk Kontainer IoC, yang terlihat seperti ini:
Untuk Ninject, khususnya, kelas Adapter beton terlihat seperti ini:
Alasan utama untuk melakukan ini adalah untuk abstrak kerangka kerja IoC, jadi saya bisa menggantinya kapan saja - mengingat bahwa perbedaan antara kerangka kerja umumnya dalam konfigurasi daripada penggunaan.
Tetapi, sebagai bonus, banyak hal juga menjadi jauh lebih mudah untuk menggunakan kerangka kerja IoC di dalam kerangka kerja lain yang tidak secara inheren mendukungnya. Untuk WinForms, misalnya, ini adalah dua langkah:
Dalam metode Utama Anda, cukup instantiate sebuah wadah sebelum melakukan hal lain.
Dan kemudian memiliki Formulir dasar, dari mana bentuk lain berasal, yang memanggil Suntikan itu sendiri.
Ini memberi tahu heuristik pengkabelan otomatis untuk mencoba menyuntikkan semua properti secara rekursif dalam bentuk yang sesuai dengan aturan yang diatur dalam modul Anda.
sumber
Penggunaan Dependency Injection yang baik biasanya bergantung pada pemisahan kode yang menciptakan objek dan logika bisnis yang sebenarnya. Dengan kata lain, saya tidak ingin tim saya sering menggunakan
new
dan membuat instance kelas seperti itu. Setelah selesai, tidak ada cara untuk dengan mudah menukar tipe yang dibuat untuk yang lain, karena Anda telah menentukan tipe konkret.Jadi ada dua cara untuk memperbaiki ini:
TestClass
ke dalam Formulir Windows Anda sehingga sudah memiliki contoh saat dibutuhkan. Ketika Ninject instantiate formulir Anda, itu secara otomatis membuat ketergantungan.IKernel
ke dalam Formulir Windows Anda, dan kemudian menggunakannya untuk instantiateTestClass
. Tergantung pada gaya Anda, ada cara lain untuk mencapai ini juga (menyuntikkan kelas pabrik, delegasi pabrik, dll).Melakukan hal ini membuatnya mudah untuk menukar tipe konkret dari TestClass, serta memodifikasi konstruksi sebenarnya dari kelas uji, tanpa benar-benar memodifikasi kode yang menggunakan kelas uji.
sumber
Saya belum pernah menggunakan Ninject, tetapi cara standar untuk membuat barang ketika Anda menggunakan IoC adalah melakukannya melalui di
Func<T>
manaT
jenis objek yang ingin Anda buat. Jadi jika objekT1
perlu membuat objek bertipeT2
maka konstruktorT1
harus memiliki parameter bertipeFunc<T1>
yang kemudian disimpan sebagai bidang / propertiT2
. Sekarang ketika Anda ingin membuat objek dari jenisT2
diT1
Anda memohonFunc
.Ini benar-benar memisahkan Anda dari kerangka kerja IoC Anda dan merupakan cara yang tepat untuk kode dalam pola pikir IoC.
Kelemahan dari melakukan ini adalah bahwa hal itu dapat mengganggu ketika Anda perlu secara manual kawat
Func
atau contoh ketika pencipta Anda memerlukan beberapa parameter, sehingga IoC tidak dapat autowireFunc
untuk Anda.http://code.google.com/p/autofac/wiki/RelationshipTypes
sumber