Saya telah menggunakan Dependency Injection (DI) untuk sementara waktu, menyuntikkan baik dalam konstruktor, properti, atau metode. Saya tidak pernah merasa perlu menggunakan wadah Inversion of Control (IoC). Namun, semakin banyak saya membaca, semakin banyak tekanan yang saya rasakan dari masyarakat untuk menggunakan wadah IoC.
Saya bermain dengan .NET container seperti StructureMap , NInject , Unity , dan Funq . Saya masih gagal melihat bagaimana wadah IoC akan menguntungkan / memperbaiki kode saya.
Saya juga takut mulai menggunakan wadah di tempat kerja karena banyak rekan kerja saya akan melihat kode yang tidak mereka mengerti. Banyak dari mereka mungkin enggan mempelajari teknologi baru.
Tolong, yakinkan saya bahwa saya perlu menggunakan wadah IOC. Saya akan menggunakan argumen ini ketika saya berbicara dengan sesama pengembang di tempat kerja.
Jawaban:
Wow, tidak percaya bahwa Joel akan menyukai ini:
lebih dari ini:
Banyak orang tidak menyadari bahwa rantai dependensi Anda dapat menjadi bersarang, dan dengan cepat menjadi sulit untuk memasang mereka secara manual. Bahkan dengan pabrik, duplikasi kode Anda tidak sepadan.
Kontainer IoC bisa rumit, ya. Tetapi untuk kasus sederhana ini saya telah menunjukkan itu sangat mudah.
Oke, mari kita benarkan ini lebih jauh. Katakanlah Anda memiliki beberapa entitas atau objek model yang ingin Anda ikat ke UI pintar. UI pintar ini (kami akan menyebutnya Shindows Morms) ingin Anda menerapkan INotifyPropertyChanged sehingga dapat melakukan perubahan pelacakan & memperbarui UI yang sesuai.
"Oke, itu tidak terdengar terlalu sulit" sehingga kamu mulai menulis.
Anda mulai dengan ini:
..dan berakhir dengan ini :
Itu kode pipa yang menjijikkan, dan saya berpendapat bahwa jika Anda menulis kode seperti itu dengan tangan Anda mencuri dari klien Anda . Ada cara kerja yang lebih baik dan lebih cerdas.
Pernah dengar istilah itu, bekerja lebih pintar, bukan lebih keras?
Bayangkan beberapa pria pintar di tim Anda muncul dan berkata: "Ini cara yang lebih mudah"
Jika Anda membuat properti Anda virtual (tenang, itu bukan masalah besar) maka kita dapat menenun dalam perilaku properti itu secara otomatis. (Ini disebut AOP, tapi jangan khawatir tentang namanya, fokus pada apa yang akan dilakukan untuk Anda)
Bergantung pada alat IoC mana yang Anda gunakan, Anda bisa melakukan sesuatu yang terlihat seperti ini:
Puf! Semua itu manual INotifyPropertyChanged BS sekarang secara otomatis dihasilkan untuk Anda, pada setiap setter properti virtual objek yang dimaksud.
Apakah ini sihir? Ya ! Jika Anda dapat mempercayai fakta bahwa kode ini melakukan tugasnya, maka Anda dapat dengan aman melewati semua properti yang membungkus mumbo-jumbo. Anda punya masalah bisnis yang harus dipecahkan.
Beberapa kegunaan lain yang menarik dari alat IoC untuk melakukan AOP:
sumber
Aku bersamamu, Vadim. Kontainer IoC mengambil konsep sederhana, elegan, dan berguna, dan menjadikannya sesuatu yang harus Anda pelajari selama dua hari dengan manual 200 halaman.
Secara pribadi saya bingung bagaimana komunitas IoC mengambil artikel yang indah dan elegan oleh Martin Fowler dan mengubahnya menjadi banyak kerangka kerja yang rumit yang biasanya dengan 200-300 halaman manual.
Saya mencoba untuk tidak menghakimi (HAHA!), Tapi saya pikir orang yang menggunakan wadah IOC adalah (A) sangat pintar dan (B) kurang empati untuk orang yang tidak sepintar mereka. Semuanya masuk akal bagi mereka, sehingga mereka kesulitan memahami bahwa banyak programmer biasa akan menemukan konsep yang membingungkan. Itu adalah kutukan pengetahuan . Orang-orang yang memahami wadah IoC kesulitan mempercayai bahwa ada orang yang tidak memahaminya.
Manfaat paling berharga dari menggunakan wadah IoC adalah Anda dapat memiliki sakelar konfigurasi di satu tempat yang memungkinkan Anda mengubah antara, misalnya, mode uji dan mode produksi. Sebagai contoh, misalkan Anda memiliki dua versi kelas akses basis data Anda ... satu versi yang masuk secara agresif dan melakukan banyak validasi, yang Anda gunakan selama pengembangan, dan versi lain tanpa pencatatan atau validasi yang sangat cepat untuk produksi. Sangat menyenangkan untuk dapat beralih di antara mereka di satu tempat. Di sisi lain, ini adalah masalah yang cukup sepele yang mudah ditangani dengan cara yang lebih sederhana tanpa kerumitan wadah IOC.
Saya percaya bahwa jika Anda menggunakan wadah IoC, kode Anda menjadi, terus terang, jauh lebih sulit dibaca. Jumlah tempat yang harus Anda perhatikan untuk mengetahui apa yang coba dilakukan oleh kode naik setidaknya satu. Dan di suatu tempat di surga seorang malaikat berteriak.
sumber
Agaknya tidak ada yang memaksa Anda untuk menggunakan kerangka wadah DI. Anda sudah menggunakan DI untuk memisahkan kelas dan meningkatkan kemampuan tes, sehingga Anda mendapatkan banyak manfaat. Singkatnya, Anda mendukung kesederhanaan, yang umumnya merupakan hal yang baik.
Jika sistem Anda mencapai tingkat kerumitan di mana DI manual menjadi tugas (yaitu, meningkatkan pemeliharaan), timbang itu terhadap kurva pembelajaran tim dari kerangka wadah DI.
Jika Anda memerlukan kontrol lebih besar atas manajemen seumur hidup ketergantungan (yaitu, jika Anda merasa perlu menerapkan pola Singleton), lihat wadah DI.
Jika Anda menggunakan wadah DI, gunakan hanya fitur yang Anda butuhkan. Lewati file konfigurasi XML dan konfigurasikan dalam kode jika cukup. Tetap menggunakan injeksi konstruktor. Dasar-dasar Unity atau StructureMap dapat diringkas menjadi beberapa halaman.
Ada posting blog yang bagus oleh Mark Seemann tentang ini: Kapan menggunakan Kontainer DI
sumber
Menurut pendapat saya manfaat nomor satu dari IoC adalah kemampuan untuk memusatkan konfigurasi dependensi Anda.
Jika saat ini Anda menggunakan injeksi Ketergantungan kode Anda mungkin terlihat seperti ini
Jika Anda menggunakan kelas IoC statis, sebagai lawan dari, IMHO file konfigurasi yang lebih membingungkan, Anda dapat memiliki sesuatu seperti ini:
Kemudian, kelas Static IoC Anda akan terlihat seperti ini, saya menggunakan Unity di sini.
sumber
Kontainer IoC juga baik untuk memuat dependensi kelas yang sangat bersarang. Sebagai contoh jika Anda memiliki kode berikut menggunakan Depedency Injection.
Jika Anda memiliki semua dependensi ini dimuat ke dalam dan wadah IoC Anda bisa Menyelesaikan Layanan Pelanggan dan semua dependensi anak akan secara otomatis diselesaikan.
Sebagai contoh:
sumber
Saya penggemar pemrograman deklaratif (lihat berapa banyak pertanyaan SQL yang saya jawab), tetapi wadah IoC yang saya lihat tampaknya terlalu misterius untuk kebaikan mereka sendiri.
... atau mungkin pengembang wadah IoC tidak mampu menulis dokumentasi yang jelas.
... atau keduanya benar untuk satu derajat atau lainnya.
Saya tidak berpikir konsep wadah IoC buruk. Tetapi implementasinya harus kuat (yaitu, fleksibel) cukup untuk berguna dalam beragam aplikasi, namun sederhana dan mudah dipahami.
Mungkin enam dari satu dan setengah lusin yang lain. Sebuah aplikasi nyata (bukan mainan atau demo) pasti kompleks, terhitung untuk banyak kasus sudut dan pengecualian terhadap aturan. Entah Anda merangkum kompleksitas dalam kode imperatif, atau yang lain dalam kode deklaratif. Tetapi Anda harus mewakilinya di suatu tempat.
sumber
Menggunakan wadah sebagian besar tentang perubahan dari gaya inisialisasi / skrip inisialisasi dan konfigurasi ke yang deklaratif . Ini mungkin memiliki beberapa efek menguntungkan yang berbeda:
Tentu saja, mungkin ada kesulitan:
sumber
Bagi saya, sepertinya Anda sudah membuat wadah IoC Anda sendiri (menggunakan berbagai pola yang dijelaskan oleh Martin Fowler) dan bertanya mengapa implementasi orang lain lebih baik daripada Anda.
Jadi, Anda memiliki banyak kode yang sudah berfungsi. Dan bertanya-tanya mengapa Anda ingin menggantinya dengan implementasi orang lain.
Pro untuk mempertimbangkan wadah IoC pihak ketiga
Cons
Jadi, timbang pro Anda melawan kontra Anda dan buat keputusan.
sumber
Saya pikir sebagian besar nilai IOC dikumpulkan dengan menggunakan DI. Karena Anda sudah melakukan itu, sisa manfaatnya bersifat inkremental.
Nilai yang Anda peroleh akan tergantung pada jenis aplikasi yang sedang Anda kerjakan:
Untuk multi-tenant, wadah IoC dapat menangani beberapa kode infrastruktur untuk memuat sumber daya klien yang berbeda. Saat Anda membutuhkan komponen yang spesifik untuk klien, gunakan pemilih khusus untuk menangani logika dan jangan khawatir tentang hal itu dari kode klien Anda. Anda tentu dapat membangun ini sendiri tetapi inilah contoh bagaimana IoC dapat membantu.
Dengan banyak titik ekstensibilitas, IoC dapat digunakan untuk memuat komponen dari konfigurasi. Ini adalah hal yang umum untuk dibangun tetapi alat disediakan oleh wadah.
Jika Anda ingin menggunakan AOP untuk beberapa masalah lintas sektoral, IoC menyediakan kait untuk mencegat pemanggilan metode. Ini jarang dilakukan secara ad-hoc pada proyek tetapi IoC membuatnya lebih mudah.
Saya telah menulis fungsionalitas seperti ini sebelumnya, tetapi jika saya memerlukan semua fitur ini sekarang saya lebih suka menggunakan alat yang sudah dibangun dan diuji jika cocok dengan arsitektur saya.
Seperti yang disebutkan oleh orang lain, Anda juga dapat mengkonfigurasi secara terpusat kelas mana yang ingin Anda gunakan. Meskipun ini bisa menjadi hal yang baik, itu datang dengan biaya penyesatan dan komplikasi. Komponen inti untuk sebagian besar aplikasi tidak banyak diganti sehingga trade-off agak sulit dibuat.
Saya menggunakan wadah IoC dan menghargai fungsi tetapi harus mengakui bahwa saya telah memperhatikan trade-off: Kode saya menjadi lebih jelas di tingkat kelas dan kurang jelas di tingkat aplikasi (yaitu memvisualisasikan aliran kontrol).
sumber
Saya seorang pecandu IOC yang sedang pulih. Saya merasa sulit untuk membenarkan menggunakan IOC untuk DI dalam banyak kasus belakangan ini. Kontainer IOC mengorbankan pemeriksaan waktu kompilasi dan konon sebagai imbalannya memberi Anda pengaturan yang "mudah", manajemen seumur hidup yang kompleks, dan penemuan dependensi saat berjalan. Saya menemukan hilangnya waktu kompilasi memeriksa dan menghasilkan run time magic / pengecualian, tidak sebanding dengan lonceng dan peluit di sebagian besar kasus. Dalam aplikasi perusahaan besar mereka dapat membuatnya sangat sulit untuk mengikuti apa yang sedang terjadi.
Saya tidak membeli argumen sentralisasi karena Anda dapat memusatkan pengaturan statis dengan sangat mudah juga dengan menggunakan pabrik abstrak untuk aplikasi Anda dan secara religius menunda pembuatan objek ke pabrik abstrak yaitu melakukan DI yang tepat.
Mengapa tidak melakukan DI statis bebas sulap seperti ini:
Konfigurasi kontainer Anda adalah implementasi pabrik abstrak Anda, pendaftaran Anda adalah implementasi dari anggota abstrak. Jika Anda memerlukan ketergantungan tunggal baru, cukup tambahkan properti abstrak lain ke pabrik abstrak. Jika Anda membutuhkan ketergantungan sementara, cukup tambahkan metode lain dan kirimkan sebagai Fungsi <>.
Keuntungan:
Saya merekomendasikan skeptis untuk mencobanya proyek lapangan hijau berikutnya dan jujur bertanya pada diri sendiri pada titik mana Anda membutuhkan wadah. Sangat mudah untuk memasukkan kontainer IOC nantinya karena Anda hanya mengganti implementasi pabrik dengan modul konfigurasi Container IOC.
sumber
Manfaat terbesar menggunakan wadah IoC untuk saya (secara pribadi, saya menggunakan Ninject) adalah untuk menghilangkan pengaturan dan berbagai objek negara global lainnya.
Saya tidak memprogram untuk web, milik saya adalah aplikasi konsol dan di banyak tempat jauh di pohon objek saya harus memiliki akses ke pengaturan atau metadata yang ditentukan oleh pengguna yang dibuat pada cabang pohon objek yang sepenuhnya terpisah. Dengan IoC saya hanya memberitahu Ninject untuk memperlakukan Pengaturan sebagai singleton (karena selalu ada hanya satu instance dari mereka), meminta Pengaturan atau Kamus di konstruktor dan presto ... mereka secara ajaib muncul ketika saya membutuhkannya!
Tanpa menggunakan wadah IoC saya harus melewati pengaturan dan / atau metadata turun melalui 2, 3, ..., dan objek sebelum benar-benar digunakan oleh objek yang membutuhkannya.
Ada banyak manfaat lain untuk wadah DI / IoC karena orang lain telah merinci di sini dan beralih dari gagasan membuat benda ke meminta benda bisa sangat membekas, tetapi menggunakan DI sangat membantu bagi saya dan tim saya sehingga mungkin Anda dapat menambahkannya ke gudang Anda!
sumber
Kerangka kerja IoC sangat baik jika Anda ingin ...
... Membuang keamanan tipe. Banyak (semua?) Kerangka kerja IoC memaksa Anda untuk mengeksekusi kode jika Anda ingin memastikan semuanya terhubung dengan benar. "Hei! Kuharap semuanya sudah diatur sehingga inisialisasi 100 kelas ini tidak akan gagal dalam produksi, melempar pengecualian null-pointer!"
... sampah kode Anda dengan GLOBALS (kerangka IOC adalah semua tentang mengubah negara global).
... tulis kode jelek dengan dependensi tidak jelas yang sulit untuk diperbaiki karena Anda tidak akan pernah tahu apa yang bergantung pada apa.
Masalahnya dengan IoC adalah orang-orang yang menggunakannya terbiasa menulis kode seperti ini
yang jelas cacat karena ketergantungan antara Foo dan Bar terprogram. Kemudian mereka menyadari akan lebih baik menulis kode seperti
yang juga cacat, tetapi kurang begitu jelas. Di Haskell tipe
Foo()
akanIO Foo
tetapi Anda benar-benar tidak ingin-IO
bagian dan harus menjadi tanda peringatan bahwa ada sesuatu yang salah dengan desain Anda jika Anda mendapatkannya.Untuk menghilangkannya (IO-part), dapatkan semua keuntungan dari IoC-frameworks dan tidak ada kekurangannya Anda bisa menggunakan pabrik abstrak.
Solusi yang tepat akan menjadi sesuatu seperti
atau mungkin
dan menyuntikkan (tapi saya tidak akan menyebutnya menyuntikkan) Bar.
Juga: lihat video ini dengan Erik Meijer (penemu LINQ) di mana ia mengatakan bahwa DI adalah untuk orang yang tidak tahu matematika (dan saya sangat setuju): http://www.youtube.com/watch?v = 8Mttjyf-8P4
Tidak seperti Mr. Spolsky, saya tidak percaya bahwa orang yang menggunakan IoC-frameworks sangat cerdas - saya hanya percaya mereka tidak tahu matematika.
sumber
IBar
, itu sebenarnyaIO IBar
) .. Dan ya, dalam contoh-Haskell Saya tidak bisa mendapatkan referensi-nol.Saya telah menemukan bahwa mengimplementasikan Dependency Injection dengan benar cenderung memaksa programmer untuk menggunakan berbagai praktik pemrograman lain yang membantu meningkatkan testabilitas, fleksibilitas, kemudahan pemeliharaan, dan skalabilitas kode: praktik seperti Prinsip Tanggung Jawab Tunggal, Pemisahan Masalah, dan pengkodean terhadap API. Rasanya seperti saya dipaksa untuk menulis lebih banyak modular, kelas dan metode berukuran gigitan, yang membuat kode lebih mudah dibaca, karena dapat diambil dalam potongan berukuran gigitan.
Tetapi juga cenderung membuat pohon ketergantungan yang agak besar, yang jauh lebih mudah dikelola melalui kerangka kerja (terutama jika Anda menggunakan konvensi) daripada dengan tangan. Hari ini saya ingin menguji sesuatu dengan sangat cepat di LINQPad, dan saya pikir akan terlalu merepotkan untuk membuat kernel dan memuat modul-modul saya, dan akhirnya saya menulis ini dengan tangan:
Dalam retrospeksi, akan lebih cepat untuk menggunakan kerangka kerja IoC, karena modul mendefinisikan hampir semua hal ini dengan konvensi.
Setelah menghabiskan beberapa waktu mempelajari jawaban dan komentar pada pertanyaan ini, saya yakin bahwa orang-orang yang menentang menggunakan wadah IoC tidak mempraktikkan injeksi ketergantungan yang sebenarnya. Contoh-contoh yang saya lihat adalah praktik yang biasanya bingung dengan injeksi ketergantungan. Beberapa orang mengeluh tentang kesulitan "membaca" kode. Jika dilakukan dengan benar, sebagian besar kode Anda harus identik ketika menggunakan DI dengan tangan seperti ketika menggunakan wadah IoC. Perbedaannya harus berada sepenuhnya dalam beberapa "titik peluncuran" dalam aplikasi.
Dengan kata lain, jika Anda tidak menyukai wadah IOC, Anda mungkin tidak melakukan Injeksi Ketergantungan seperti yang seharusnya dilakukan.
Poin lain: Ketergantungan Injeksi benar-benar tidak dapat dilakukan dengan tangan jika Anda menggunakan refleksi di mana saja. Meskipun saya benci refleksi yang dilakukan terhadap navigasi kode, Anda harus mengenali bahwa ada area tertentu yang tidak dapat dihindari. ASP.NET MVC, misalnya, mencoba untuk instantiate controller melalui refleksi pada setiap permintaan. Untuk melakukan injeksi dependensi dengan tangan, Anda harus menjadikan setiap controller "root konteks", seperti:
Sekarang bandingkan ini dengan memungkinkan kerangka kerja DI melakukannya untuk Anda:
Menggunakan kerangka kerja DI, perhatikan bahwa:
ISimpleWorkflowInstanceMerger
, saya bisa menguji apakah itu digunakan dengan cara yang saya perkirakan, tanpa perlu koneksi database atau apa pun.ISimpleWorkflowInstanceMerger
antarmuka. Ini memungkinkan saya untuk memecah aplikasi menjadi modul terpisah, dan mempertahankan arsitektur multi-tier yang sebenarnya, yang pada gilirannya membuat semuanya menjadi lebih fleksibel.Aplikasi web tipikal akan memiliki beberapa pengontrol. Semua rasa sakit melakukan DI dengan tangan di setiap pengontrol akan bertambah seiring dengan bertambahnya aplikasi Anda. Jika Anda memiliki aplikasi dengan hanya satu konteks root, yang tidak pernah mencoba untuk instantiate layanan dengan refleksi, maka ini bukan masalah besar. Namun demikian, aplikasi apa pun yang menggunakan Dependency Injection akan menjadi sangat mahal untuk dikelola setelah mencapai ukuran tertentu, kecuali jika Anda menggunakan semacam kerangka kerja untuk mengelola grafik dependensi.
sumber
Setiap kali Anda menggunakan kata kunci "baru", Anda menciptakan ketergantungan kelas yang konkret dan bel alarm kecil akan berbunyi di kepala Anda. Menjadi lebih sulit untuk menguji objek ini secara terpisah. Solusinya adalah memprogram untuk antarmuka dan menyuntikkan dependensi sehingga objek dapat diuji unit dengan apa pun yang mengimplementasikan antarmuka itu (mis. Mengolok-olok).
Masalahnya adalah Anda harus membuat objek di suatu tempat. Pola Pabrik adalah salah satu cara untuk menggeser kopling dari POXO Anda (Biasa Lama "masukkan bahasa OO Anda di sini" Objek). Jika Anda dan rekan kerja Anda semua menulis kode seperti ini maka wadah IoC adalah "Peningkatan Bertambah" berikutnya yang dapat Anda buat ke basis kode Anda. Ini akan menggeser semua kode boiler Pabrik jahat dari objek bersih dan logika bisnis Anda. Mereka akan mendapatkannya dan menyukainya. Heck, bicarakan perusahaan mengapa Anda menyukainya dan buat semua orang bersemangat.
Jika rekan kerja Anda belum melakukan DI, maka saya sarankan Anda fokus dulu. Sebarkan berita tentang cara menulis kode bersih yang mudah diuji. Bersihkan kode DI adalah bagian yang sulit, begitu Anda berada di sana, memindahkan objek logika kabel dari kelas Pabrik ke wadah IoC harus relatif sepele.
sumber
Karena semua dependensi terlihat jelas, itu mempromosikan pembuatan komponen yang longgar digabungkan dan pada saat yang sama mudah diakses dan digunakan kembali di seluruh aplikasi.
sumber
Anda tidak perlu wadah IOC.
Tetapi jika Anda dengan ketat mengikuti pola DI, Anda akan menemukan bahwa memiliki satu akan menghilangkan satu ton kode yang berlebihan dan membosankan.
Itu sering kali merupakan waktu terbaik untuk menggunakan perpustakaan / kerangka kerja - ketika Anda memahami apa yang dilakukannya dan bisa melakukannya tanpa perpustakaan.
sumber
Saya kebetulan sedang dalam proses menarik keluar kode DI rumah tumbuh dan menggantinya dengan IOC. Saya mungkin telah menghapus lebih dari 200 baris kode dan menggantinya dengan sekitar 10. Ya, saya harus melakukan sedikit belajar tentang cara menggunakan wadah (Winsor), tapi saya seorang insinyur yang bekerja pada teknologi internet di Abad 21 jadi saya sudah terbiasa dengan itu. Saya mungkin menghabiskan sekitar 20 menit untuk melihat bagaimana caranya. Ini sepadan dengan waktu saya.
sumber
Ketika Anda terus memisahkan kelas-kelas Anda dan membalikkan dependensi Anda, kelas-kelas terus tetap kecil dan "grafik ketergantungan" terus bertambah besar. (Ini tidak buruk.) Menggunakan fitur dasar wadah IoC membuat kabel semua benda ini sepele, tetapi melakukannya secara manual bisa menjadi sangat memberatkan. Misalnya, bagaimana jika saya ingin membuat instance baru "Foo" tetapi perlu "Bar". Dan "Bar" membutuhkan "A", "B", dan "C". Dan masing-masing dari mereka memerlukan 3 hal lain, dll. (Ya, saya tidak dapat membuat nama palsu yang bagus :)).
Menggunakan wadah IoC untuk membuat grafik objek Anda mengurangi kompleksitas satu ton dan mendorongnya ke dalam konfigurasi satu kali. Saya hanya mengatakan "buatkan saya 'Foo'" dan itu mencari tahu apa yang diperlukan untuk membangun satu.
Beberapa orang menggunakan wadah IoC untuk infrastruktur yang jauh lebih banyak, yang bagus untuk skenario tingkat lanjut, tetapi dalam kasus itu saya setuju itu dapat mengaburkan dan membuat kode sulit dibaca dan debug untuk pengembang baru.
sumber
Dittos tentang Persatuan. Menjadi terlalu besar, dan Anda dapat mendengar derit di kasau.
Tidak pernah mengejutkan saya ketika orang-orang mulai menyemburkan tentang bagaimana kode IoC terlihat bersih adalah jenis yang sama dari orang-orang yang pada suatu waktu berbicara tentang bagaimana templat dalam C ++ adalah cara elegan untuk kembali di tahun 90-an, namun saat ini akan mengutuk mereka sebagai sesuatu yang misterius. . Bah!
sumber
Di dunia .NET AOP tidak terlalu populer, jadi untuk DI framework adalah satu-satunya pilihan nyata Anda, apakah Anda menulis sendiri atau menggunakan framework lain.
Jika Anda menggunakan AOP, Anda dapat menyuntikkan ketika Anda mengkompilasi aplikasi Anda, yang lebih umum di Jawa.
Ada banyak manfaat untuk DI, seperti pengurangan kopling sehingga pengujian unit lebih mudah, tetapi bagaimana Anda akan menerapkannya? Apakah Anda ingin menggunakan refleksi untuk melakukannya sendiri?
sumber
Jadi, sudah hampir 3 tahun, kan?
50% dari mereka yang berkomentar mendukung kerangka kerja IoC tidak memahami perbedaan antara kerangka kerja IoC dan IoC. Saya ragu mereka tahu bahwa Anda dapat menulis kode tanpa disebarkan ke server aplikasi
Jika kita mengambil kerangka Java Spring paling populer, itu adalah konfigurasi IoC yang dipindahkan dari XMl ke dalam kode dan sekarang terlihat seperti ini
`@Configation public class AppConfig {
} `Dan kita perlu kerangka kerja untuk melakukan ini mengapa tepatnya?
sumber
Jujur saya tidak menemukan ada banyak kasus di mana wadah IoC diperlukan, dan sebagian besar waktu, mereka hanya menambah kompleksitas yang tidak dibutuhkan.
Jika Anda menggunakannya hanya untuk membuat konstruksi objek lebih sederhana, saya harus bertanya, apakah Anda membuat instance objek ini di lebih dari satu lokasi? Apakah lajang tidak sesuai dengan kebutuhan Anda? Apakah Anda mengubah konfigurasi saat runtime? (Mengalihkan tipe sumber data, dll).
Jika ya, maka Anda mungkin perlu wadah IOC. Jika tidak, maka Anda hanya memindahkan inisialisasi dari tempat pengembang dapat dengan mudah melihatnya.
Siapa bilang antarmuka lebih baik daripada warisan? Katakanlah Anda sedang menguji Layanan. Mengapa tidak menggunakan konstruktor DI, dan membuat ejekan dependensi menggunakan warisan? Sebagian besar layanan yang saya gunakan hanya memiliki sedikit ketergantungan. Melakukan pengujian unit dengan cara ini mencegah pemeliharaan satu ton antarmuka yang tidak berguna dan berarti Anda tidak harus menggunakan Resharper untuk dengan cepat menemukan deklarasi suatu metode.
Saya percaya bahwa untuk sebagian besar implementasi, mengatakan bahwa IoC Containers menghapus kode yang tidak dibutuhkan adalah mitos.
Pertama, ada pengaturan wadah di tempat pertama. Maka Anda masih harus mendefinisikan setiap objek yang perlu diinisialisasi. Jadi Anda tidak menyimpan kode dalam inisialisasi, Anda memindahkannya (kecuali objek Anda digunakan lebih dari sekali. Apakah lebih baik sebagai Singleton?). Kemudian, untuk setiap objek yang Anda inisialisasi dengan cara ini, Anda harus membuat dan memelihara antarmuka.
Adakah yang punya pemikiran tentang ini?
sumber
ShippingCostCalculator
atauProductUIPresentation
, atau strategi / implementasi lainnya, dalam basis kode yang sama persis , dengan menggunakan hanya satu file XML yang diubah.Anda akan membutuhkan wadah IoC jika Anda perlu memusatkan konfigurasi dependensi Anda sehingga mereka dapat dengan mudah diganti secara massal. Ini paling masuk akal dalam TDD, di mana banyak dependensi ditukar, tetapi di mana ada sedikit saling ketergantungan antara dependensi. Hal ini dilakukan pada biaya yang mengaburkan aliran kontrol konstruksi objek sampai taraf tertentu, sehingga memiliki konfigurasi yang terorganisir dengan baik dan didokumentasikan secara wajar adalah penting. Ini juga baik untuk memiliki alasan untuk melakukan ini, jika tidak, itu hanyalah abstraksi penyepuhan emas . Saya telah melihat itu dilakukan dengan sangat buruk sehingga diseret menjadi setara dengan pernyataan goto untuk konstruktor.
sumber
Inilah sebabnya. Proyek ini disebut IOC-with-Ninject. Anda dapat mengunduh dan menjalankannya dengan Visual Studio. Contoh ini menggunakan Ninject tetapi SEMUA pernyataan 'baru' ada di satu lokasi dan Anda dapat sepenuhnya mengubah cara aplikasi Anda berjalan dengan mengubah modul bind mana yang akan digunakan. Contohnya diatur sehingga Anda dapat mengikat ke versi layanan yang diejek atau versi nyata. Dalam proyek-proyek kecil yang mungkin tidak masalah, tetapi dalam proyek-proyek besar itu adalah masalah besar.
Supaya jelas, keuntungan seperti yang saya lihat: 1) SEMUA pernyataan baru di satu lokasi di root kode. 2) Benar-benar kode faktor ulang dengan satu perubahan. 3) Poin ekstra untuk 'faktor keren' karena itu ... well: keren. : p
sumber
Saya akan mencoba mencari tahu mengapa IOC mungkin tidak baik dari sudut pandang saya.
Seperti yang lainnya, wadah IOC (atau seperti yang dikatakan Einstein, I = OC ^ 2) adalah konsep yang harus Anda putuskan sendiri apakah Anda membutuhkannya atau tidak dalam kode Anda. Teriakan mode terbaru tentang IOC hanya itu, mode. Jangan jatuh cinta pada mode, itu yang pertama. Ada banyak sekali konsep di luar sana yang bisa Anda terapkan dalam kode Anda. Pertama-tama, saya menggunakan injeksi dependensi sejak saya memulai pemrograman, dan mempelajari istilah itu sendiri ketika dipopulerkan dengan nama itu. Kontrol ketergantungan adalah subjek yang sangat tua dan telah ditangani sejauh ini dalam triliunan cara, tergantung pada apa yang dipisahkan dari apa. Memisahkan segala sesuatu dari segalanya adalah omong kosong. Masalah dengan wadah IOC adalah bahwa ia mencoba untuk menjadi sama bermanfaatnya dengan Entity Framework atau NHibernate. Sementara menulis mapper-objek relasional hanyalah suatu keharusan segera setelah Anda harus memasangkan setiap database dengan sistem Anda, wadah IOC tidak selalu diperlukan. Jadi ketika wadah IOC berguna:
1: Ini tidak sering bahwa Anda memiliki begitu banyak dependensi dalam kode Anda, atau bahwa Anda menyadarinya sejak awal desain. Berpikir abstrak berguna ketika berpikir abstrak adalah karena.
2: Menggabungkan kode Anda dengan kode pihak ketiga adalah masalah HuGe. Saya bekerja dengan kode yang berumur 10+ tahun dan pada saat itu mengikuti konsep mewah dan canggih ATL, COM, COM + dan seterusnya. Tidak ada yang dapat Anda lakukan dengan kode itu sekarang. Apa yang saya katakan adalah bahwa konsep lanjutan memberikan keuntungan yang jelas, namun ini dibatalkan pada akhirnya dengan keuntungan yang sudah usang itu sendiri. Itu hanya membuat semuanya lebih mahal.
3: Pengembangan perangkat lunak cukup sulit. Anda dapat memperluasnya ke tingkat yang tidak dapat dikenali jika Anda mengizinkan beberapa konsep lanjutan untuk memotong kode Anda. Ada masalah dengan IOC2. Meskipun dependensi decoupling, itu decoupling aliran logika juga. Bayangkan Anda telah menemukan bug dan Anda perlu istirahat untuk memeriksa situasinya. IOC2, seperti konsep lanjutan lainnya, membuatnya semakin sulit. Memperbaiki bug dalam konsep lebih sulit daripada memperbaiki bug dalam kode yang lebih jelas, karena ketika Anda memperbaiki bug konsep harus dipatuhi lagi. (Hanya untuk memberi Anda contoh, C ++. NET terus-menerus mengubah sintaks sehingga Anda harus berpikir keras sebelum Anda refactor beberapa versi .NET.) Jadi, apa masalah dengan IOC? Masalahnya adalah dalam menyelesaikan dependensi. Logika untuk menyelesaikan umumnya tersembunyi di IOC2 itu sendiri, ditulis mungkin dengan cara tidak biasa yang perlu Anda pelajari dan pelihara. Apakah produk pihak ketiga Anda akan ada di sana dalam 5 tahun? Microsoft tidak.
Sindrom "Kami tahu bagaimana" ditulis di semua tempat mengenai IOC2. Ini mirip dengan pengujian otomatisasi. Istilah mewah dan solusi sempurna pada pandangan pertama, Anda cukup melakukan semua tes untuk dieksekusi pada malam hari dan melihat hasilnya di pagi hari. Sangat menyakitkan untuk menjelaskan perusahaan demi perusahaan apa arti pengujian otomatis sebenarnya. Pengujian otomatis jelas bukan cara cepat untuk mengurangi jumlah bug yang dapat Anda perkenalkan semalam untuk meningkatkan kualitas produk Anda. Tapi, fesyen membuat gagasan itu dominan dan mengganggu. IOC2 menderita sindrom yang sama. Dipercaya bahwa Anda perlu mengimplementasikannya agar perangkat lunak Anda menjadi baik. Setiap wawancara baru-baru ini saya ditanya apakah saya menerapkan IOC2 dan otomatisasi. Itu adalah tanda mode: perusahaan memiliki beberapa bagian kode yang ditulis dalam MFC yang tidak akan mereka tinggalkan.
Anda perlu mempelajari IOC2 seperti konsep lain dalam perangkat lunak. Keputusan jika IOC2 perlu digunakan ada di dalam tim dan perusahaan. Namun, setidaknya SEMUA argumen di atas harus disebutkan sebelum keputusan dibuat. Hanya jika Anda melihat sisi positifnya melebihi sisi negatifnya, Anda dapat membuat keputusan positif.
Tidak ada yang salah dengan IOC2 kecuali bahwa itu hanya menyelesaikan masalah yang dipecahkan dan memperkenalkan masalah yang diperkenalkannya. Tidak ada lagi. Namun, menentang mode sangat sulit, mereka memiliki mulut yang berkeringat, pengikut apa pun. Sungguh aneh bagaimana tidak satu pun dari mereka ada di sana ketika masalah dengan keanggunan mereka menjadi jelas. Banyak konsep dalam industri perangkat lunak telah dipertahankan karena mereka menghasilkan laba, buku ditulis, konferensi diadakan, produk baru dibuat. Itu fashion, biasanya berumur pendek. Begitu orang menemukan sesuatu yang lain, mereka meninggalkannya sepenuhnya. IOC2 berguna tetapi menunjukkan tanda-tanda yang sama seperti banyak konsep lenyap lainnya yang pernah saya lihat. Saya tidak tahu apakah itu akan bertahan. Tidak ada aturan untuk itu. Anda pikir jika itu berguna, itu akan bertahan. Tidak, tidak seperti itu. Satu perusahaan kaya besar sudah cukup dan konsepnya bisa mati dalam beberapa minggu. Kita lihat saja nanti. NHibernate selamat, EF berada di urutan kedua. Mungkin IOC2 akan bertahan juga. Jangan lupa bahwa sebagian besar konsep dalam pengembangan perangkat lunak adalah tentang tidak ada yang istimewa, mereka sangat logis, sederhana dan jelas, dan kadang-kadang lebih sulit untuk mengingat konvensi penamaan saat ini daripada memahami konsep itu sendiri. Apakah pengetahuan IOC2 membuat pengembang menjadi pengembang yang lebih baik? Tidak, karena jika pengembang tidak dapat membuat konsep yang mirip dengan IOC2 maka akan sulit baginya untuk memahami masalah yang diselesaikan oleh IOC2, menggunakannya akan terlihat buatan dan dia mungkin mulai menggunakannya demi menjadi semacam politik yang benar. Jangan lupa bahwa sebagian besar konsep dalam pengembangan perangkat lunak adalah tentang tidak ada yang istimewa, mereka sangat logis, sederhana dan jelas, dan kadang-kadang lebih sulit untuk mengingat konvensi penamaan saat ini daripada memahami konsep itu sendiri. Apakah pengetahuan IOC2 membuat pengembang menjadi pengembang yang lebih baik? Tidak, karena jika pengembang tidak dapat membuat konsep yang mirip dengan IOC2 maka akan sulit baginya untuk memahami masalah yang diselesaikan oleh IOC2, menggunakannya akan terlihat buatan dan dia mungkin mulai menggunakannya demi menjadi semacam politik yang benar. Jangan lupa bahwa sebagian besar konsep dalam pengembangan perangkat lunak adalah tentang tidak ada yang istimewa, mereka sangat logis, sederhana dan jelas, dan kadang-kadang lebih sulit untuk mengingat konvensi penamaan saat ini daripada memahami konsep itu sendiri. Apakah pengetahuan IOC2 membuat pengembang menjadi pengembang yang lebih baik? Tidak, karena jika pengembang tidak dapat membuat konsep yang mirip dengan IOC2 maka akan sulit baginya untuk memahami masalah yang diselesaikan oleh IOC2, menggunakannya akan terlihat buatan dan dia mungkin mulai menggunakannya demi menjadi semacam politik yang benar. Apakah pengetahuan IOC2 membuat pengembang menjadi pengembang yang lebih baik? Tidak, karena jika pengembang tidak dapat membuat konsep yang mirip dengan IOC2 maka akan sulit baginya untuk memahami masalah yang diselesaikan oleh IOC2, menggunakannya akan terlihat buatan dan dia mungkin mulai menggunakannya demi menjadi semacam politik yang benar. Apakah pengetahuan IOC2 membuat pengembang menjadi pengembang yang lebih baik? Tidak, karena jika pengembang tidak dapat membuat konsep yang mirip dengan IOC2 maka akan sulit baginya untuk memahami masalah yang diselesaikan oleh IOC2, menggunakannya akan terlihat buatan dan dia mungkin mulai menggunakannya demi menjadi semacam politik yang benar.
sumber
Secara pribadi, saya menggunakan IoC sebagai semacam peta struktur aplikasi saya (Ya, saya juga lebih suka StructureMap;)). Itu membuatnya mudah untuk menggantikan implementasi antarmuka biasa saya dengan implementasi Moq selama tes. Membuat setup tes bisa semudah membuat init-call baru ke IoC-framework saya, menggantikan kelas mana saja yang merupakan batas-test saya dengan mock.
Ini mungkin bukan untuk apa IoC ada, tapi itulah yang saya temukan paling banyak saya gunakan ..
sumber
IOC CONTAINER MENYELESAIKAN MASALAH YANG ANDA TIDAK BISA MEMILIKI TETAPI MASALAH YANG BAGUS UNTUK MEMILIKI
http://kozmic.net/2012/10/23/ioc-container-solves-a-problem-you-might-not-have-but-its-a-nice-problem-to-have/
sumber
Anda tidak perlu kerangka kerja untuk mencapai injeksi ketergantungan. Anda dapat melakukan ini dengan konsep inti java juga. http://en.wikipedia.org/wiki/Dependency_injection#Code_illustration_using_Java
sumber
Saya menyadari ini posting yang agak lama, tetapi tampaknya masih cukup aktif, dan saya pikir saya akan berkontribusi beberapa poin yang belum disebutkan dalam jawaban lain.
Saya akan mengatakan bahwa saya setuju dengan manfaat injeksi ketergantungan, tetapi saya lebih memilih untuk membangun dan mengelola objek sendiri, menggunakan pola yang tidak seperti yang diuraikan oleh Maxm007 dalam jawabannya. Saya telah menemukan dua masalah utama dengan menggunakan wadah pihak ke-3:
1) Memiliki perpustakaan pihak ke-3 yang mengatur masa pakai objek Anda "secara otomatis" dapat memberikan hasil yang tidak terduga. Kami telah menemukan bahwa terutama dalam proyek besar, Anda dapat memiliki salinan objek yang jauh lebih banyak daripada yang Anda harapkan, dan lebih banyak daripada yang Anda lakukan jika Anda mengelola siklus hidup secara manual. Saya yakin ini bervariasi tergantung pada kerangka yang digunakan, tetapi masalahnya tetap ada. Ini juga bisa menjadi masalah jika objek Anda menyimpan sumber daya, koneksi data, dll., Karena objek kadang-kadang bisa hidup lebih lama dari yang Anda harapkan. Jadi mau tidak mau, wadah IoC cenderung meningkatkan pemanfaatan sumber daya dan jejak memori aplikasi.
2) Kontainer IoC, menurut pendapat saya, adalah bentuk "pemrograman kotak hitam". Saya telah menemukan bahwa khususnya, pengembang kami yang kurang berpengalaman cenderung menyalahgunakan mereka. Hal ini memungkinkan programmer untuk tidak harus berpikir tentang bagaimana benda harus berhubungan satu sama lain atau bagaimana memisahkan mereka, karena itu memberi mereka mekanisme di mana mereka dapat dengan mudah mengambil benda apa pun yang mereka inginkan dari udara tipis. Misalnya, mungkin ada alasan desain yang baik bahwa ObjectA seharusnya tidak pernah tahu tentang ObjectB secara langsung, tetapi daripada membuat pabrik atau jembatan atau pencari layanan, programmer yang tidak berpengalaman hanya akan mengatakan "tidak masalah, saya hanya akan mengambil ObjectB dari wadah IoC ". Ini benar-benar dapat menyebabkan peningkatan kopling objek, yang seharusnya membantu mencegah IoC.
sumber
Ketergantungan Injeksi dalam proyek ASP.NET dapat diselesaikan dengan beberapa baris kode. Saya kira ada beberapa keuntungan menggunakan wadah ketika Anda memiliki aplikasi yang menggunakan beberapa ujung depan dan membutuhkan pengujian unit.
sumber