Apa definisi terbaik untuk Injeksi Ketergantungan?


10

Setiap kali seseorang menghubungi saya dan meminta saya untuk mendefinisikan Injeksi Ketergantungan dalam cara konseptual dan menjelaskan pro dan kontra yang sebenarnya dalam menggunakan DI dalam desain perangkat lunak. Saya mengakui bahwa saya memiliki beberapa kesulitan untuk menjelaskan konsep-konsep DI. Setiap kali saya perlu memberi tahu mereka sejarah tentang prinsip tanggung jawab tunggal, komposisi atas warisan, dll.

Adakah yang bisa membantu saya menjelaskan cara terbaik untuk menggambarkan DI untuk pengembang?


2
Tantangannya di sini adalah bahwa ada banyak definisi DI yang saling bertentangan. Saya mengambil sikap "DI murni": jika saya memiliki fungsi yang bergantung pada parameternya untuk menyediakan semua status, data dll, maka fungsi tersebut menggunakan DI. Pada ekstrem yang lain, beberapa akan berpendapat bahwa tanpa kerangka kerja DI, tidak ada injeksi ketergantungan (meskipun mereka tentu saja salah;)). Jadi, kecuali Anda dapat menentukan definisi, Anda tidak dapat mulai menjelaskan apa itu ...
David Arno

Jadi, seperti yang saya mengerti, ini bukan hanya masalah saya.
Tiago Sampaio



Semuanya bermuara pada ini: injeksi ketergantungan adalah salah satu teknik yang digunakan untuk mencapai inversi ketergantungan; yang lainnya hanyalah hal-hal tambahan yang dibangun di atasnya. Perhatikan bahwa dalam dua istilah ini kata "ketergantungan" memiliki arti yang sedikit berbeda. Dalam injeksi dependensi, ini merujuk pada komponen yang menjadi sandaran kode. Dalam inversi ketergantungan, ini merujuk pada hubungan (diarahkan) itu sendiri - hubungan yang ingin kita balikkan. Yang terakhir adalah tujuannya, jadi pro dan kontra utamanya adalah sama; ditambah beberapa masalah tambahan terkait dengan implementasi aktual, seperti manajemen objek seumur hidup.
Filip Milovanović

Jawaban:


22

Dependency Injection adalah nama yang mengerikan (IMO) 1 untuk konsep yang agak langsung. Ini sebuah contoh:

  1. Anda memiliki metode (atau kelas dengan metode) yang melakukan X (mis. Mengambil data dari basis data)
  2. Sebagai bagian dari melakukan X, metode tersebut menciptakan dan mengelola sumber daya internal (misalnya a DbContext). Sumber daya internal inilah yang disebut dependensi
  3. Anda menghapus pembuatan dan pengelolaan sumber daya (yaitu DbContext) dari metode dan menjadikannya penelepon tanggung jawab untuk menyediakan sumber daya ini (sebagai parameter metode atau berdasarkan instantiasi kelas)
  4. Anda sekarang melakukan injeksi ketergantungan.


[1] : Saya berasal dari latar belakang tingkat bawah dan butuh waktu berbulan-bulan untuk duduk dan belajar injeksi ketergantungan karena namanya menyiratkan itu akan menjadi sesuatu yang jauh lebih rumit, seperti DLL Injection . Fakta bahwa Visual Studio (dan kami pengembang pada umumnya) merujuk ke .NET libraries (DLLs, atau assemblies ) yang bergantung pada proyek karena dependensi tidak membantu sama sekali. Bahkan ada yang namanya Dependency Walker (depend.exe) .


[Sunting] Saya pikir beberapa kode demo akan berguna untuk beberapa, jadi inilah satu (dalam C #).

Tanpa injeksi ketergantungan:

public class Repository : IDisposable
{
    protected DbContext Context { get; }

    public Repository()
    {
        Context = new DbContext("name=MyEntities");
    }

    public void Dispose()
    {
        Context.Dispose();
    }
}

Konsumen Anda kemudian akan melakukan sesuatu seperti:

using ( var repository = new Repository() )
{
    // work
}

Kelas yang sama diimplementasikan dengan pola injeksi ketergantungan akan seperti ini:

public class RepositoryWithDI
{
    protected DbContext Context { get; }

    public RepositoryWithDI(DbContext context)
    {
        Context = context;
    }
}

Sekarang responsabilitas penelepon untuk membuat instance DbContextdan meneruskan (errm, menyuntikkan ) ke kelas Anda:

using ( var context = new DbContext("name=MyEntities") )
{
    var repository = new RepositoryWithDI(context);

    // work
}

3
Ini harus ditambahkan ke Wikipedia.
Evorlor

2
Sekarang responsabilitas penelepon untuk membuat instance DbContext - Saya pikir ini akan menjadi tanggung jawab titik masuk aplikasi untuk membuat instantiasi semua dependensi yang diperlukan. Jadi konsumen hanya perlu memperkenalkan tipe yang diperlukan sebagai ketergantungan dalam kontrak sendiri.
Fabio

@Fabio Bisa jadi. (Dalam hal ini tanggung jawab penelepon akan menyediakan sumber daya yang dipakai pada saat startup aplikasi untuk metode / kelas yang dipanggil.) Dalam contoh saya, tidak, karena itu bukan persyaratan untuk menjelaskan konsep injeksi ketergantungan .
Marc.2377

5

Konsep abstrak seringkali lebih baik dijelaskan dengan menggunakan analogi dunia nyata. Ini analogi saya:

Anda menjalankan toko sandwich. Anda membuat sandwich yang luar biasa, tetapi Anda tidak tahu banyak tentang roti itu sendiri. Anda hanya memiliki roti tawar putih. Pekerjaan Anda sepenuhnya berfokus pada topping yang Anda gunakan untuk mengubah roti menjadi sandwich.

Namun, beberapa pelanggan Anda akan lebih suka roti cokelat. Beberapa lebih suka gandum utuh. Anda tidak terlalu peduli, Anda bisa membuat sandwich yang luar biasa asalkan roti dengan ukuran yang sama. Anda juga benar-benar tidak ingin harus mengambil tanggung jawab tambahan dalam pengadaan beberapa jenis roti dan menjaga persediaan. Bahkan jika Anda menyimpan beberapa jenis roti, akan selalu ada pelanggan dengan rasa eksotis pada roti yang tidak dapat Anda bayangkan sebelumnya.

Jadi, Anda melembagakan aturan baru: pelanggan membawa roti mereka sendiri. Anda tidak lagi menyediakan roti sendiri. Ini adalah situasi win-win: pelanggan bisa mendapatkan roti persis yang mereka inginkan, dan Anda tidak perlu lagi repot-repot membeli roti yang tidak Anda pedulikan. Bagaimanapun, Anda pembuat sandwich, bukan pembuat roti.

Oh, dan untuk mengakomodasi para pelanggan yang tidak ingin membeli roti mereka sendiri, Anda membuka toko kedua di sebelah yang menjual roti putih hambar asli Anda. Pelanggan yang tidak membawa roti sendiri hanya perlu mendapatkan yang default dan kemudian datang kepada Anda untuk membuat sandwich dengan itu.

Itu tidak sempurna tetapi menyoroti fitur utama: memberikan kontrol kepada konsumen . Win-win yang melekat adalah bahwa Anda tidak lagi harus mendapatkan dependensi Anda sendiri, dan konsumen Anda tidak terhalang dalam pilihan ketergantungan mereka.


1
Saya suka ini tetapi OP sedang mencari penjelasan untuk pengembang . Abstraksi awal itu baik, tetapi cepat atau lambat, itu akan membutuhkan contoh kehidupan nyata.
Robbie Dee

1
@RobbieDee: Ketika tujuan dari pola ini jelas, implementasinya juga cenderung menjadi jelas. Sebagai contoh, jawaban Marc benar-benar benar, tetapi saya merasa penjelasannya macet karena sifat kompleks dari situasi contoh yang ia gunakan. Ini bermuara pada "Jika Anda ingin membangun kapal, jangan goyang orang untuk mengumpulkan kayu dan tidak menugaskan mereka tugas dan pekerjaan, tetapi mengajar mereka untuk merindukan luasnya laut yang tak berujung." . Daripada menjelaskan apa yang harus dilakukan, saya lebih suka menjelaskan mengapa melakukannya.
Flater

2
Anda tentu saja benar, tetapi saya tidak bisa tidak berpikir saya akan membutuhkan contoh nyata - seperti tidak memiliki sistem file atau database nyata untuk membangkitkan selera saya, tetapi mungkin itu hanya pandangan pengembang saya yang sempit :)
Robbie Dee

1

Jawaban sederhana untuk itu:

Pertama-tama kelas harus memiliki tanggung jawab yang jelas, dan segala sesuatu di luar lingkup ini harus disimpan di luar kelas itu. Dengan ini, Ketergantungan Injeksi adalah ketika Anda menyuntikkan fungsionalitas dari kelas B lainnya ke dalam kelas A menggunakan bantuan dari "pihak ketiga" untuk mencapai pemisahan kekhawatiran ini, membantu kelas A untuk menyelesaikan beberapa operasi yang berada di luar cakupannya.

.Net Core adalah contoh yang cukup bagus yang dapat Anda berikan karena kerangka kerja ini menggunakan banyak injeksi ketergantungan. Secara umum, layanan yang ingin Anda injeksi terletak di startup.csfile.

Tentu, siswa harus menyadari beberapa konsep seperti polimorfisme, antarmuka dan prinsip-prinsip Desain OOP.


0

Ada banyak bulu dan bunkum di sekitar apa, pada dasarnya, konsep sederhana.

Juga sangat mudah untuk terjebak dengan " kerangka kerja apa yang harus saya gunakan " ketika Anda bisa melakukannya cukup sederhana dalam kode.

Ini adalah definisi yang saya gunakan secara pribadi:

Diberikan perilaku X dengan ketergantungan Y. Injeksi ketergantungan melibatkan fasilitas untuk memasok setiap Y yang memenuhi kriteria untuk menjadi contoh dari Y, bahkan jika Anda tidak memilikinya.

Beberapa contoh mungkin di mana Y adalah sistem file atau koneksi database.

Kerangka kerja seperti moq memungkinkan doubles (versi pretend Y) didefinisikan menggunakan antarmuka sehingga dimungkinkan untuk menyuntikkan instance Y, di mana Y misalnya, koneksi database.

Sangat mudah untuk jatuh ke dalam perangkap percaya bahwa ini murni masalah pengujian unit tetapi ini adalah pola yang sangat berguna untuk setiap bit kode di mana perubahan diharapkan dan bisa dibilang, adalah praktik yang baik pula.


0

Kami memberikan perilaku fungsi saat runtime melalui metode memasukkan perilaku itu ke dalam fungsi melalui parameter.

Pola Strategi adalah contoh yang sangat baik dari injeksi ketergantungan.


0

Untuk melakukan ini dengan benar, pertama-tama kita harus mendefinisikan dependensi dan injeksi.

  • Ketergantungan: sumber daya apa pun yang dibutuhkan operasi.
  • Injeksi: meneruskan sumber daya itu ke operasi, biasanya sebagai argumen untuk suatu metode.

Contoh mendasar akan menjadi metode yang menambahkan dua nilai. Jelas, metode ini membutuhkan nilai yang akan ditambahkan. Jika mereka diberikan dengan memberikannya sebagai argumen, ini akan menjadi kasus injeksi ketergantungan. Alternatifnya adalah dengan mengimplementasikan operan sebagai properti atau variabel global. Dengan cara itu tidak ada dependensi akan disuntikkan, dependensi akan tersedia dimuka secara eksternal.

Misalkan Anda menggunakan properti saja dan Anda menamainya A dan B. Jika Anda mengubah nama menjadi Op1 dan Op2, Anda akan merusak metode Tambahkan. Atau IDE Anda akan memperbarui semua nama untuk Anda, intinya adalah metode ini perlu diperbarui juga karena memiliki ketergantungan pada sumber daya eksternal.

Contoh ini dasar tetapi Anda dapat membayangkan contoh yang lebih kompleks di mana metode melakukan operasi pada objek seperti gambar atau di mana ia membaca dari aliran file. Apakah Anda ingin metode menjangkau untuk gambar, mengharuskannya untuk tahu di mana itu? Tidak. Apakah Anda ingin metode untuk membuka file itu sendiri, memerlukannya untuk mengetahui di mana mencari file atau bahkan tahu itu akan membaca dari file? Tidak.

Intinya: untuk mengurangi fungsionalitas metode ke perilaku intinya dan memisahkan metode dari lingkungannya. Anda mendapatkan yang pertama dengan melakukan yang kedua, Anda dapat mempertimbangkan definisi injeksi ketergantungan ini.

Manfaat: karena ketergantungan pada lingkungan metode telah dihilangkan, perubahan pada metode tidak akan berdampak pada lingkungan dan sebaliknya. => Aplikasi menjadi lebih mudah untuk memelihara (memodifikasi).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.