Apakah Serialisasi mencegah penggunaan Injeksi Ketergantungan?

9

Pertanyaan sederhana: Saya mengerti bahwa serialisasi dalam C # memerlukan konstruktor default. Ini akan menghilangkan kemungkinan menggunakan Constructor injected DI (yang umumnya merupakan gaya yang disukai DI, dalam bacaan saya [rujukan?] ). Jadi, apakah ini benar-benar sebuah situasi, atau apakah saya kehilangan sesuatu?

(Pertanyaan sampingan): Apakah kontainer IoC memihak tradeoff ini?

kmote
sumber
This would eliminate the possibility of using Constructor injected DI- Kenapa? Anda masih dapat memiliki instruktur berparameter, selama Anda menyertakan konstruktor default untuk keperluan serialisasi (konstruktor default dapat bersifat pribadi, jika Anda mau).
Robert Harvey
@RobertHarvey: Saya merasa agak padat, tapi saya tidak mengerti. Apa itu "instruktur berparameter"? (salah ketik?) Setelah sebuah objek telah di-serialisasi, saya tidak dapat membangunnya lagi. Apakah Anda menyarankan saya menggunakan injeksi properti / setter pada objek yang dibuat secara default?
kmote
1
Konstruktor berparameter adalah konstruktor dengan parameter. Saya berasumsi di sini bahwa deserialisasi terjadi dari data yang berasal dari objek yang dibangun dengan benar menggunakan injeksi ketergantungan. Anda tidak harus membuat objek selama deserialisasi; itu sudah dibangun sebelumnya.
Robert Harvey
1
Tidak, kamu tidak salah. Begitulah cara kerjanya. Anggap saja sebagai injeksi pintu belakang. Anda tidak akan mendapatkan validasi apa pun, tetapi itu akan berhasil. Perhatikan bahwa BinaryFormatter dan DataContractSerializer tidak memerlukan konstruktor default.
Robert Harvey
1
Untuk menjadi jelas, semua deserialization dilakukan adalah mengisi keadaan di objek Anda dengan nilai-nilai yang ditentukan dalam objek XML. Ini menggunakan Refleksi untuk mencapai ini, dan memotong segala bentuk logika validasi konstruktor, jadi dari perspektif DI, itu curang, kecuali nilai-nilai XML itu awalnya berasal dari objek yang dibangun melalui DI biasa.
Robert Harvey

Jawaban:

6

Tidak mungkin untuk menderialisasi serial objek dan juga menyuntikkan dependensi ke objek lain yang sudah ada, dalam satu langkah dalam C #, menggunakan mekanisme serialisasi standar. Anda harus menggunakan injeksi properti, pertama membangun objek menggunakan deserializer, kemudian menyuntikkan ketergantungan. Untuk sebagian besar aplikasi dunia nyata, saya tidak menganggap ini sebagai kelemahan nyata - jika Anda memiliki kelas model data berseri, yang juga tergantung pada kelas model non-data lainnya, Anda harus memeriksa apakah kelas model data Anda mungkin memiliki sudah terlalu banyak tanggung jawab.

Jika itu benar-benar mengganggu Anda, Anda dapat mempertimbangkan untuk membungkus objek serializable Anda dengan kelas dekorator, di mana Anda dapat melewati de-serializer dan dependensi tambahan melalui konstruktor. Pembungkus itu kemudian mengeksekusi dua langkah (de-serialisasi objek terbungkus dan injeksi properti) dalam konstruktornya.

Doc Brown
sumber
1

Saya memecahkan masalah ini seperti itu: menyuntikkan pabrik ketergantungan. Di pabrik-pabrik itu, pertama-tama selesaikan ketergantungan karena terdaftar dalam wadah, kemudian "deserialisasi" semua data yang tersisa: json.net memungkinkan untuk mengisi bidang dalam objek yang ada.

Karena kode pabrik sejalan dengan kode kabel wadah IoC, saya tidak berpikir menggunakan container.Resolvedi dalam pabrik melanggar aturan, yang containerharus digunakan hanya di satu tempat dalam kode: di mana semua kabel terjadi.

Sampai sekarang, saya mencoba untuk membuat proses ini otomatis (sebagai lawan dari apa yang saya telah menguji pendekatan itu di) menggunakan refleksi. Ya, tidak banyak yang tersisa dari deserialisasi json.net itu sendiri, bagian dari itu diganti dengan kode kustom, tapi saya pikir, mengapa repot-repot.

Juga, apa pemikiran / keputusan akhir Anda tentang masalah ini? Setelah membaca posting ini saya melihat dua cara: deserialize, lalu suntikkan; atau menyuntikkan, lalu deserialize (mengisi). Dan saya masih menemukan cara saya lebih baik. Akan senang mendengar argumen yang bertentangan dengan ini (saya kira, bahwa cara saya mungkin lebih baik untuk kasus saya, tetapi tidak dapat dengan jelas membayangkan kasus alternatif yang baik, di mana gagal, hanya beberapa tebakan kecil)

jungle_mole
sumber