pengembangan-web-mp.com

Apa itu injeksi ketergantungan?

Ada beberapa pertanyaan yang sudah diposting dengan pertanyaan spesifik tentang injeksi ketergantungan , seperti kapan menggunakannya dan kerangka kerja apa yang tersedia untuk itu. Namun,

Apa itu injeksi ketergantungan dan kapan/mengapa harus atau tidak harus digunakan?

2811
AR.

Pada dasarnya, alih-alih membuat objek Anda membuat ketergantungan atau meminta objek pabrik untuk membuatnya, Anda meneruskan dependensi yang diperlukan ke objek secara eksternal, dan Anda menjadikannya masalah orang lain. "Seseorang" ini adalah objek yang lebih jauh dari grafik dependensi, atau injector dependensi (kerangka kerja) yang membangun grafik dependensi. Ketergantungan seperti yang saya gunakan di sini adalah objek lain yang dibutuhkan objek saat ini untuk referensi.

Salah satu keuntungan utama dari injeksi ketergantungan adalah dapat membuat pengujian lebih mudah. Misalkan Anda memiliki objek yang dalam konstruktornya melakukan sesuatu seperti:

public SomeClass() {
    myObject = Factory.getObject();
}

Ini bisa merepotkan ketika semua yang ingin Anda lakukan adalah menjalankan beberapa tes unit pada SomeClass, terutama jika myObject adalah sesuatu yang melakukan disk kompleks atau akses jaringan. Jadi sekarang Anda melihat mengejek myObject tetapi juga entah bagaimana mencegat panggilan pabrik. Keras. Alih-alih, masukkan objek sebagai argumen ke konstruktor. Sekarang Anda telah memindahkan masalah ke tempat lain, tetapi pengujian dapat menjadi jauh lebih mudah. Buat saja dummy myObject dan berikan itu. Konstruktor sekarang akan terlihat seperti:

public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

Ini adalah satu gaya injeksi ketergantungan - melalui konstruktor. Beberapa mekanisme dimungkinkan. 

  • Seperti dicatat dalam komentar, satu alternatif umum adalah mendefinisikan konstruktor do-nothing, dan meminta dependensi disuntikkan melalui setter properti (h/t @MikeVella). 
  • Martin Fowler mendokumentasikan alternatif ketiga (h/t @MarcDix), di mana kelas secara eksplisit mengimplementasikan antarmuka untuk dependensi yang ingin mereka injeksi.

Ketika tidak menggunakan injeksi dependensi (seperti di kelas yang melakukan terlalu banyak pekerjaan di konstruktor, dll.), Cenderung menjadi lebih sulit untuk mengisolasi komponen dalam pengujian unit. 

Kembali pada tahun 2013 ketika saya menulis jawaban ini, ini adalah tema utama di Google Testing Blog . Ini tetap menjadi keuntungan terbesar bagi saya, karena Anda mungkin tidak selalu membutuhkan fleksibilitas ekstra dalam desain run-time Anda (misalnya, untuk pencari lokasi atau pola yang serupa), tetapi Anda seringkali harus dapat mengisolasi kelas Anda selama pengujian.

1764
wds

Definisi terbaik yang saya temukan sejauh ini adalah satu oleh James Shore

"Injeksi Ketergantungan" adalah 25 dolar. istilah untuk konsep 5 sen. [...] Injeksi ketergantungan berarti memberikan objek variabel contohnya. [...].

Ada artikel oleh Martin Fowler yang mungkin terbukti bermanfaat juga.

Ketergantungan injeksi pada dasarnya menyediakan objek yang dibutuhkan suatu objek (dependensinya) alih-alih membuatnya membangunnya sendiri. Ini adalah teknik yang sangat berguna untuk pengujian, karena memungkinkan dependensi untuk dipermainkan atau dihilangkan.

Ketergantungan dapat disuntikkan ke objek dengan banyak cara (seperti injeksi konstruktor atau injeksi setter). Seseorang bahkan dapat menggunakan kerangka kerja injeksi ketergantungan khusus (mis. Spring) untuk melakukan itu, tetapi tentu saja tidak diperlukan. Anda tidak perlu kerangka kerja itu untuk memiliki injeksi ketergantungan. Instantiating dan melewatkan objek (dependensi) secara eksplisit sama baiknya dengan injeksi oleh kerangka kerja.

2167
Thiago Arrais

Saya menemukan contoh lucu ini dalam hal lepas kopling :

Aplikasi apa pun terdiri dari banyak objek yang saling berkolaborasi untuk melakukan beberapa hal berguna. Secara tradisional setiap objek bertanggung jawab untuk mendapatkan referensi sendiri ke objek dependen (dependensi) yang dikolaborasikan dengannya. Ini mengarah ke kelas yang sangat berpasangan dan kode yang sulit untuk diuji.

Sebagai contoh, pertimbangkan objek Car.

Sebuah Car tergantung pada roda, mesin, bahan bakar, baterai, dll untuk dijalankan. Secara tradisional kami mendefinisikan merek dari objek dependen tersebut bersama dengan definisi dari objek Car.

Tanpa Injeksi Ketergantungan (DI):

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

Di sini, objek Carbertanggung jawab untuk membuat objek dependen.

Bagaimana jika kita ingin mengubah jenis objek dependennya - katakan Wheel - setelah tusukan NepaliRubberWheel() awal? Kita perlu membuat ulang objek Mobil dengan dependensi barunya ChineseRubberWheel(), tetapi hanya pabrikan Car yang bisa melakukan itu.

Lalu untuk apa kita Dependency Injection lakukan ...?

Saat menggunakan injeksi dependensi, objek diberi dependensi mereka pada waktu berjalan daripada waktu kompilasi (waktu pembuatan mobil) . Sehingga kita sekarang dapat mengubah Wheel kapan pun kita mau. Di sini, dependency (wheel) dapat disuntikkan ke Car pada saat run time.

Setelah menggunakan injeksi dependensi:

Di sini, kita menyuntikkan the dependensi (Roda dan Baterai) saat runtime. Karenanya istilah: Injeksi Ketergantungan. 

class Car{
  private Wheel wh = [Inject an Instance of Wheel (dependency of car) at runtime]
  private Battery bt = [Inject an Instance of Battery (dependency of car) at runtime]
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

Sumber: Memahami injeksi ketergantungan

554
gtiwari333

Dependency Injection adalah praktik di mana objek dirancang dengan cara di mana mereka menerima instance objek dari potongan kode lain, alih-alih membangunnya secara internal. Ini berarti bahwa objek apa pun yang mengimplementasikan antarmuka yang diperlukan oleh objek dapat diganti tanpa mengubah kode, yang menyederhanakan pengujian, dan meningkatkan decoupling.

Sebagai contoh, pertimbangkan klausa ini:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
} 

Dalam contoh ini, implementasi PersonService::addManager dan PersonService::removeManager akan membutuhkan turunan GroupMembershipService untuk melakukan tugasnya. Tanpa Injeksi Ketergantungan, cara tradisional untuk melakukan ini adalah dengan instantiate GroupMembershipService baru dalam konstruktor PersonService dan menggunakan atribut instance itu di kedua fungsi. Namun, jika konstruktor GroupMembershipService memiliki beberapa hal yang diperlukan, atau lebih buruk lagi, ada beberapa "setter" inisialisasi yang perlu dipanggil pada GroupMembershipService, kode tumbuh agak cepat, dan PersonService sekarang tidak hanya bergantung pada GroupMembershipService tetapi juga segala sesuatu yang bergantung pada GroupMembershipService. Selain itu, tautan ke GroupMembershipService di-hardcode ke PersonService yang berarti Anda tidak bisa "membuat-buat" a GroupMembershipService untuk tujuan pengujian, atau menggunakan pola strategi di berbagai bagian aplikasi Anda. 

Dengan Dependency Injection, alih-alih instantiating GroupMembershipService dalam PersonService Anda, Anda akan meneruskannya ke konstruktor PersonService, atau menambahkan Properti (pengambil dan penyetel) untuk menetapkan contoh lokal dari itu. Ini berarti bahwa PersonService Anda tidak perlu lagi khawatir tentang cara membuat GroupMembershipService, ia hanya menerima yang telah diberikan, dan bekerja dengannya. Ini juga berarti bahwa apa pun yang merupakan subclass dari GroupMembershipService, atau mengimplementasikan antarmuka GroupMembershipService dapat "disuntikkan" ke PersonService, dan PersonService tidak perlu tahu tentang perubahan.

241
Adam Ness

Jawaban yang diterima adalah jawaban yang bagus - tetapi saya ingin menambahkan bahwa DI sangat mirip dengan klasik yang menghindari konstanta hardcode dalam kode. 

Ketika Anda menggunakan konstanta seperti nama basis data, Anda akan dengan cepat memindahkannya dari bagian dalam kode ke beberapa file konfigurasi dan meneruskan variabel yang berisi nilai itu ke tempat yang diperlukan. Alasan untuk melakukan itu adalah bahwa konstanta ini biasanya berubah lebih sering daripada sisa kode. Misalnya jika Anda ingin menguji kode dalam database pengujian. 

DI analog dengan ini di dunia pemrograman Berorientasi Objek. Nilai di sana alih-alih literal konstan adalah objek keseluruhan - tetapi alasan untuk memindahkan kode yang membuatnya dari kode kelas serupa - objek lebih sering berubah daripada kode yang menggunakannya. Satu kasus penting di mana perubahan semacam itu diperlukan adalah tes.

155
zby

Mari kita coba contoh sederhana dengan kelas Mobil dan Mesin, mobil apa pun membutuhkan mesin untuk pergi ke mana pun, setidaknya untuk saat ini. Jadi di bawah ini bagaimana kode akan terlihat tanpa injeksi ketergantungan.

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

Dan untuk membuat instance kelas Mobil kita akan menggunakan kode berikutnya:

Car car = new Car();

Masalah dengan kode ini yang kami gabungkan dengan erat ke GasEngine dan jika kami memutuskan untuk mengubahnya menjadi ElectricityEngine maka kami perlu menulis ulang kelas Car. Dan semakin besar aplikasinya, semakin banyak masalah dan sakit kepala yang harus kita tambahkan dan gunakan jenis mesin baru. 

Dengan kata lain dengan pendekatan ini adalah bahwa kelas mobil tingkat tinggi kami bergantung pada kelas GasEngine tingkat bawah yang melanggar Prinsip Ketergantungan Inversi (DIP) dari SOLID. DIP menyarankan bahwa kita harus bergantung pada abstraksi, bukan kelas konkret. Jadi untuk memuaskan ini kami memperkenalkan antarmuka IEngine dan menulis ulang kode seperti di bawah ini:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

Sekarang kelas Mobil kami hanya bergantung pada antarmuka IEngine, bukan implementasi mesin yang spesifik. Sekarang, satu-satunya trik adalah bagaimana kita membuat turunan dari Mobil dan memberikan kelas Mesin beton yang nyata seperti GasEngine atau ElectricityEngine. Di situlah Injeksi Ketergantungan muncul. 

   Car gasCar = new Car(new GasEngine());
   gasCar.Run();
   Car electroCar = new Car(new ElectricityEngine());
   electroCar.Run();

Di sini kita pada dasarnya menyuntikkan (meneruskan) ketergantungan kita (contoh mesin) ke konstruktor Mobil. Jadi sekarang kelas kami memiliki kopling longgar antara objek dan dependensinya, dan kami dapat dengan mudah menambahkan jenis mesin baru tanpa mengubah kelas Mobil.

Manfaat utama dari Ketergantungan Injeksi bahwa kelas lebih longgar digabungkan, karena mereka tidak memiliki dependensi hard-coded. Ini mengikuti Prinsip Ketergantungan Inversi, yang disebutkan di atas. Alih-alih merujuk implementasi spesifik, kelas meminta abstraksi (biasanya antarmuka) yang diberikan kepada mereka ketika kelas dibangun.

Jadi pada akhirnya Injeksi ketergantungan hanyalah teknik untuk mencapai kopling longgar antara objek dan dependensinya . Daripada secara langsung instantiating dependensi yang dibutuhkan kelas dalam Untuk melakukan tindakannya, dependensi disediakan untuk kelas (paling sering) melalui injeksi konstruktor.

Juga ketika kita memiliki banyak dependensi, adalah praktik yang sangat baik untuk menggunakan wadah Inversion of Control (IoC) yang dapat kita beri tahu interface mana yang harus dipetakan ke implementasi konkret untuk semua dependensi kita dan kita dapat memilikinya menyelesaikan dependensi tersebut untuk kita ketika ia membangun objek kita. Sebagai contoh, kita dapat menentukan dalam pemetaan untuk wadah IoC bahwa ketergantungan IEngine harus dipetakan ke kelas GasEngine dan ketika kita meminta wadah IoC untuk instance dari kelas Car , ini akan secara otomatis membangun kelas Mobil kami dengan ketergantungan GasEngine

UPDATE: Menyaksikan kursus tentang EF Core dari Julie Lerman baru-baru ini dan juga menyukai definisi singkatnya tentang DI.

Injeksi ketergantungan adalah pola yang memungkinkan aplikasi Anda menyuntikkan objek dengan cepat ke kelas yang membutuhkannya, tanpa memaksa mereka. kelas untuk bertanggung jawab atas objek tersebut. Ini memungkinkan kode Anda menjadi lebih longgar digabungkan, dan Entity Framework Core terhubung ke .__ yang sama ini. sistem layanan.

103
user2771704

Bayangkan Anda ingin memancing:

  • Tanpa injeksi ketergantungan, Anda harus mengurus semuanya sendiri. Anda perlu menemukan perahu, membeli pancing, mencari umpan, dll. Itu mungkin, tentu saja, tetapi menempatkan banyak tanggung jawab pada Anda. Dalam istilah perangkat lunak, itu berarti Anda harus melakukan pencarian untuk semua hal ini.

  • Dengan injeksi ketergantungan, orang lain mengurus semua persiapan dan membuat peralatan yang diperlukan tersedia untuk Anda. Anda akan menerima ("disuntikkan") perahu, pancing dan umpan - semuanya siap digunakan.

102
Olivier Liechti

Ini adalah penjelasan paling sederhana tentang Dependency Injection dan Dependency Injection Container Saya pernah melihat:

Tanpa Injeksi Ketergantungan

  • Aplikasi membutuhkan Foo (mis. Pengontrol), jadi:
  • Aplikasi menciptakan Foo
  • Aplikasi memanggil Foo
    • Foo membutuhkan Bilah (mis. Layanan), jadi:
    • Foo menciptakan Bar
    • Foo memanggil Bar
      • Bar membutuhkan Bim (layanan, repositori, …), Jadi:
      • Bar menciptakan Bim
      • Bar melakukan sesuatu

Dengan Injeksi Ketergantungan

  • Aplikasi membutuhkan Foo, yang membutuhkan Bar, yang membutuhkan Bim, jadi:
  • Aplikasi menciptakan Bim
  • Aplikasi menciptakan Bar dan memberinya Bim
  • Aplikasi menciptakan Foo dan memberinya Bar
  • Aplikasi memanggil Foo
    • Foo memanggil Bar
      • Bar melakukan sesuatu

Menggunakan Wadah Injeksi Ketergantungan

  • Aplikasi membutuhkan Foo jadi:
  • Aplikasi mendapat Foo dari Container, jadi:
    • Wadah menciptakan Bim
    • Container menciptakan Bar dan memberinya Bim
    • Container menciptakan Foo dan memberinya Bar
  • Aplikasi memanggil Foo
    • Foo memanggil Bar
      • Bar melakukan sesuatu

Injeksi Ketergantungan dan dependensi Injeksi Kontainer adalah hal yang berbeda:

  • Ketergantungan Injeksi adalah metode untuk menulis kode yang lebih baik
  • wadah DI adalah alat untuk membantu menyuntikkan dependensi

Anda tidak perlu wadah untuk melakukan injeksi ketergantungan. Namun sebuah wadah dapat membantu Anda.

86
Trix

Bukankah "injeksi ketergantungan" hanya berarti menggunakan konstruktor berparameter dan setter publik?

Artikel James Shore menunjukkan contoh-contoh berikut untuk perbandingan .

Pembuat tanpa injeksi ketergantungan:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

Pembuat dengan injeksi ketergantungan:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}
49
JaneGoodall

Untuk membuat konsep Ketergantungan Injeksi mudah dipahami. Mari kita ambil contoh tombol sakelar untuk menghidupkan (mematikan/mematikan) bohlam.

Tanpa Injeksi Ketergantungan

Switch perlu tahu sebelumnya bohlam mana saya terhubung (ketergantungan kode keras). Begitu,

Switch -> Switch PermanentBulb // terhubung langsung ke bola lampu permanen, pengujian tidak dimungkinkan dengan mudah

 

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

Dengan Injeksi Ketergantungan

Switch hanya tahu saya harus menghidupkan/mematikan Bulb mana pun yang diberikan kepada saya. Begitu,

Beralih -> Bulb1 OR Bulb2 OR NightBulb (ketergantungan yang diinjeksi)

 

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

Mengubah James Contoh untuk Switch dan Bulb:

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`
33
wakqasahmed

Semua jawaban di atas bagus, tujuan saya adalah menjelaskan konsep dengan cara yang sederhana sehingga siapa pun yang tidak memiliki pengetahuan pemrograman juga dapat memahami konsep

Injeksi ketergantungan adalah salah satu pola desain yang membantu kita menciptakan sistem yang kompleks dengan cara yang lebih sederhana.

Kita dapat melihat berbagai macam aplikasi dari pola ini dalam kehidupan kita sehari-hari . Beberapa contohnya adalah tape recorder, VCD, CD Drive dll.

 Reel-to-reel portable tape recorder, mid-20th century.

Gambar di atas adalah gambar dari tape recorder portabel Reel-to-reel, pertengahan abad ke-20. Sumber .

Tujuan utama dari mesin perekam adalah untuk merekam atau memutar suara.

Saat mendesain sistem, diperlukan gulungan untuk merekam atau memutar suara atau musik. Ada dua kemungkinan untuk merancang sistem ini

  1. kita dapat menempatkan gulungan di dalam mesin
  2. kami dapat menyediakan kait untuk gulungan di mana ia dapat ditempatkan.

Jika kita menggunakan yang pertama, kita perlu membuka mesin untuk mengganti gulungan ... ... jika kita memilih yang kedua, yaitu memasang kait untuk gulungan, kita mendapatkan manfaat tambahan dari memainkan musik apa pun dengan mengubah gulungan. . dan juga mengurangi fungsi hanya untuk memainkan apa pun di reel.

Seperti injeksi dependensi yang bijak adalah proses mengeksternalisasi dependensi untuk fokus hanya pada fungsionalitas spesifik komponen sehingga komponen independen dapat digabungkan bersama untuk membentuk sistem yang kompleks.

Manfaat utama yang kami raih dengan menggunakan injeksi ketergantungan.

  • Kohesi tinggi dan kopling longgar.
  • Mengalirkan ketergantungan dan hanya melihat pada tanggung jawab.
  • Menjadikan hal-hal sebagai komponen dan bergabung membentuk sistem besar dengan kemampuan tinggi.
  • Ini membantu untuk mengembangkan komponen berkualitas tinggi karena mereka dikembangkan secara independen mereka diuji dengan baik.
  • Ini membantu untuk mengganti komponen dengan yang lain jika ada yang gagal.

Sekarang suatu hari konsep ini membentuk dasar dari kerangka kerja yang terkenal di dunia pemrograman ..__ Spring Angular dll adalah kerangka kerja perangkat lunak terkenal yang dibangun di atas konsep ini.

Dependency injection adalah pola yang digunakan untuk membuat instance objek yang diandalkan objek lain tanpa mengetahui pada waktu kompilasi kelas mana yang akan digunakan untuk menyediakan fungsionalitas itu atau hanya cara menyuntikkan properti ke objek yang disebut dependensi injeksi.

Contoh untuk injeksi Ketergantungan

Sebelumnya kami menulis kode seperti ini

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

Dengan injeksi Dependency, injector dependensi akan melepas instantiation untuk kita 

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

Anda juga bisa membaca

Perbedaan antara Pembalikan Kontrol & Ketergantungan Injeksi

18
Samuel J Mathew

Apa itu Injeksi Ketergantungan?

Dependency Injection (DI) berarti memisahkan objek yang saling bergantung. Katakanlah objek A bergantung pada Obyek B sehingga idenya adalah untuk memisahkan objek ini dari satu sama lain. Kami tidak perlu melakukan hard code pada objek menggunakan kata kunci baru, alih-alih membagikan dependensi ke objek saat runtime meskipun waktu kompilasi . 

Cara Kerja Dependency Injection di Spring:

Kami tidak perlu melakukan hard code pada objek menggunakan kata kunci baru daripada mendefinisikan ketergantungan kacang pada file konfigurasi. Wadah pegas akan bertanggung jawab untuk menghubungkan semua.

Inversion of Control (IOC)

IOC adalah konsep umum dan dapat diekspresikan dengan berbagai cara dan Dependency Injection adalah salah satu contoh nyata IOC.

Dua jenis Injeksi Ketergantungan:

  1. Injeksi Konstruktor
  2. Setter Injection

1. Injeksi ketergantungan berbasis konstruktor:

DI berbasis konstruktor dicapai ketika wadah memanggil konstruktor kelas dengan sejumlah argumen, masing-masing mewakili ketergantungan pada kelas lain.

public class Triangle {

private String type;

public String getType(){
    return type;
 }

public Triangle(String type){   //constructor injection
    this.type=type;
 }
}
<bean id=triangle" class ="com.test.dependencyInjection.Triangle">
        <constructor-arg value="20"/>
  </bean>

2. Injeksi ketergantungan setter-based:

DI berbasis setter dilakukan dengan kontainer memanggil metode setter pada kacang Anda setelah memanggil konstruktor tanpa argumen atau metode pabrik statis tanpa argumen untuk membuat instance kacang Anda.

public class Triangle{

 private String type;

 public String getType(){
    return type;
  }
 public void setType(String type){          //setter injection
    this.type = type;
  }
 }

<!-- setter injection -->
 <bean id="triangle" class="com.test.dependencyInjection.Triangle">
        <property name="type" value="equivialteral"/>

CATATAN: Ini adalah aturan praktis yang baik untuk menggunakan argumen konstruktor untuk dependensi wajib dan setter untuk dependensi opsional. Perhatikan bahwa jika kita menggunakan anotasi berdasarkan @ annotasi yang dibutuhkan pada setter dapat digunakan untuk menjadikan setter sebagai dependensi yang diperlukan.

17
Harleen

Analogi terbaik yang dapat saya pikirkan adalah ahli bedah dan asistennya di ruang operasi, di mana ahli bedah adalah orang utama dan asistennya yang menyediakan berbagai komponen bedah ketika ia membutuhkannya sehingga ahli bedah dapat berkonsentrasi pada satu hal yang ia lakukan terbaik (operasi). Tanpa asisten, ahli bedah harus mendapatkan komponen sendiri setiap kali ia membutuhkannya.

Singkatnya, DI adalah teknik untuk menghilangkan tanggung jawab tambahan umum (beban) pada komponen untuk mengambil komponen dependen, dengan menyediakannya.

DI membawa Anda lebih dekat ke prinsip Tanggung Jawab Tunggal (SR), seperti surgeon who can concentrate on surgery.

Kapan harus menggunakan DI: Saya akan merekomendasikan menggunakan DI di hampir semua proyek produksi (kecil/besar), terutama di lingkungan bisnis yang selalu berubah :)

Mengapa: Karena Anda ingin kode Anda mudah diuji, dapat dipermainkan dll sehingga Anda dapat dengan cepat menguji perubahan Anda dan Dorong ke pasar. Selain itu mengapa Anda tidak ketika Anda memiliki banyak alat/kerangka kerja gratis yang mengagumkan untuk mendukung Anda dalam perjalanan Anda ke basis kode di mana Anda memiliki kontrol lebih.

15
Anwar Husain

Ini berarti bahwa objek hanya memiliki dependensi sebanyak yang diperlukan untuk melakukan pekerjaannya dan dependensi harus sedikit. Selain itu, dependensi objek harus berada pada antarmuka dan bukan pada objek "konkret", bila memungkinkan. (Objek konkret adalah objek apa pun yang dibuat dengan kata kunci baru.) Kopling longgar mempromosikan penggunaan kembali yang lebih besar, pemeliharaan lebih mudah, dan memungkinkan Anda untuk dengan mudah memberikan objek "tiruan" di tempat layanan mahal.

"Injeksi Ketergantungan" (DI) juga dikenal sebagai "Pembalikan Kontrol" (IoC), dapat digunakan sebagai teknik untuk mendorong sambungan longgar ini.

Ada dua pendekatan utama untuk mengimplementasikan DI:

  1. Injeksi konstruktor 
  2. Injeksi setter

Injeksi konstruktor

Ini adalah teknik meneruskan ketergantungan objek kepada konstruktornya.

Perhatikan bahwa konstruktor menerima antarmuka dan bukan objek konkret. Juga, perhatikan bahwa pengecualian dilemparkan jika parameter orderDao adalah nol. Ini menekankan pentingnya menerima ketergantungan yang valid. Injeksi Konstruktor adalah, menurut pendapat saya, mekanisme yang disukai untuk memberikan objek dependensinya. Jelas bagi pengembang sambil memanggil objek yang dependensi perlu diberikan ke objek "Orang" untuk eksekusi yang tepat.

Setter Injection

Tetapi perhatikan contoh berikut ... Misalkan Anda memiliki kelas dengan sepuluh metode yang tidak memiliki dependensi, tetapi Anda menambahkan metode baru yang memang memiliki ketergantungan pada IDAO. Anda dapat mengubah konstruktor untuk menggunakan Injeksi Konstruktor, tetapi ini dapat memaksa Anda untuk mengubah semua panggilan konstruktor di semua tempat. Atau, Anda bisa menambahkan konstruktor baru yang menggunakan dependensi, tetapi kemudian bagaimana pengembang dengan mudah tahu kapan harus menggunakan satu konstruktor di atas yang lain. Akhirnya, jika ketergantungan sangat mahal untuk dibuat, mengapa itu harus dibuat dan diteruskan ke konstruktor padahal mungkin hanya jarang digunakan? "Setter Injection" adalah teknik DI lainnya yang dapat digunakan dalam situasi seperti ini.

Setter Injection tidak memaksa ketergantungan untuk diteruskan ke konstruktor. Alih-alih, dependensi diatur ke properti publik yang terpapar oleh objek yang membutuhkan. Seperti yang tersirat sebelumnya, motivator utama untuk melakukan ini meliputi:

  1. Mendukung injeksi ketergantungan tanpa harus memodifikasi konstruktor kelas warisan.
  2. Mengizinkan sumber daya atau layanan mahal dibuat selambat mungkin dan hanya jika diperlukan.

Berikut adalah contoh bagaimana kode di atas akan terlihat seperti:

public class Person {
    public Person() {}

    public IDAO Address {
        set { addressdao = value; }
        get {
            if (addressdao == null)
              throw new MemberAccessException("addressdao" +
                             " has not been initialized");
            return addressdao;
        }
    }

    public Address GetAddress() {
       // ... code that uses the addressdao object
       // to fetch address details from the datasource ...
    }

    // Should not be called directly;
    // use the public property instead
    private IDAO addressdao;
13

Contoh, kami memiliki 2 kelas Client dan Service. Client akan menggunakan Service

public class Service {
    public void doSomeThingInService() {
        // ...
    }
}

Tanpa Injeksi Ketergantungan

Way 1) 

public class Client {
    public void doSomeThingInClient() {
        Service service = new Service();
        service.doSomeThingInService();
    }
}

Way 2)

public class Client {
    Service service = new Service();
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

Way 3) 

public class Client {
    Service service;
    public Client() {
        service = new Service();
    }
    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

1) 2) 3) Menggunakan

Client client = new Client();
client.doSomeThingInService();

Keuntungan

  • Sederhana

Kekurangan

  • Sulit untuk ujian kelas Client
  • Ketika kita mengubah konstruktor Service, kita perlu mengubah kode di semua tempat membuat objek Service

Gunakan Injeksi Ketergantungan

Cara 1) Injeksi konstruktor

public class Client {
    Service service;

    Client(Service service) {
        this.service = service;
    }

    // Example Client has 2 dependency 
    // Client(Service service, IDatabas database) {
    //    this.service = service;
    //    this.database = database;
    // }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

Menggunakan 

Client client = new Client(new Service());
// Client client = new Client(new Service(), new SqliteDatabase());
client.doSomeThingInClient();

Way 2) Setter injection

public class Client {
    Service service;

    public void setService(Service service) {
        this.service = service;
    }

    public void doSomeThingInClient() {
        service.doSomeThingInService();
    }
}

Menggunakan 

Client client = new Client();
client.setService(new Service());
client.doSomeThingInClient();

Way 3) Antarmuka injeksi

Periksa https://en.wikipedia.org/wiki/Dependency_injection

=== 

Sekarang, kode ini sudah mengikuti Dependency Injection dan lebih mudah untuk menguji kelas Client.
Namun, kami masih menggunakan new Service() berkali-kali dan itu tidak baik ketika mengubah Service konstruktor. Untuk mencegahnya, kita bisa menggunakan injektor DI
1) Manual sederhana Injector

public class Injector {
    public static Service provideService(){
        return new Service();
    }

    public static IDatabase provideDatatBase(){
        return new SqliteDatabase();
    }
    public static ObjectA provideObjectA(){
        return new ObjectA(provideService(...));
    }
}

Menggunakan

Service service = Injector.provideService();

2) Gunakan perpustakaan: Untuk Android dagger2

Keuntungan

  • Buat tes lebih mudah
  • Ketika Anda mengubah Service, Anda hanya perlu mengubahnya di kelas Injector
  • Jika Anda menggunakan Constructor Injection, ketika Anda melihat konstruktor Client, Anda akan melihat berapa banyak ketergantungan dari Client kelas

Kekurangan 

  • Jika Anda menggunakan Constructor Injection, objek Service dibuat ketika Client dibuat, kadang-kadang kita menggunakan fungsi di kelas Client tanpa menggunakan Service sehingga dibuat Service jadi sia-sia

Definisi Injeksi Ketergantungan

https://en.wikipedia.org/wiki/Dependency_injection

Ketergantungan adalah objek yang dapat digunakan (Service)
Suntikan adalah melewati dependensi (Service) ke objek dependen (Client) yang akan menggunakannya

12
Linh

Saya pikir karena semua orang telah menulis untuk DI, izinkan saya mengajukan beberapa pertanyaan ..

  1. Ketika Anda memiliki konfigurasi DI di mana semua implementasi aktual (bukan antarmuka) yang akan disuntikkan ke dalam kelas (misalnya layanan ke controller) mengapa itu bukan semacam hard-coding? 
  2. Bagaimana jika saya ingin mengubah objek saat runtime? Sebagai contoh, konfigurasi saya sudah mengatakan ketika saya instantiate MyController, menyuntikkan FileLogger sebagai ILogger. Tapi saya mungkin ingin menyuntikkan DatabaseLogger. 
  3. Setiap kali saya ingin mengubah objek apa yang dibutuhkan AClass saya, sekarang saya perlu melihat ke dua tempat - Kelas itu sendiri dan file konfigurasi. Bagaimana itu membuat hidup lebih mudah?
  4. Jika Aproperty of AClass tidak disuntikkan, apakah lebih sulit untuk mengejeknya? 
  5. Kembali ke pertanyaan pertama. Jika menggunakan objek baru () buruk, kenapa kita menyuntikkan implementasi dan bukan antarmuka? Saya pikir banyak dari Anda mengatakan kami sebenarnya menyuntikkan antarmuka tetapi konfigurasi membuat Anda menentukan implementasi antarmuka itu .. bukan pada saat runtime .. itu hardcoded selama waktu kompilasi.

Ini berdasarkan jawaban @Adam N yang diposting.

Mengapa PersonService tidak perlu lagi khawatir tentang GroupMembershipService? Anda baru saja menyebutkan bahwa GroupMembership memiliki banyak hal (objek/properti) yang tergantung padanya. Jika GMService diperlukan di PService, Anda akan memilikinya sebagai properti. Anda dapat mengejek itu terlepas dari apakah Anda menyuntikkannya atau tidak. Satu-satunya waktu saya ingin disuntikkan adalah jika GMService memiliki kelas anak yang lebih spesifik, yang Anda tidak akan tahu sampai runtime. Maka Anda ingin menyuntikkan subclass. Atau jika Anda ingin menggunakannya sebagai singleton atau prototipe. Sejujurnya, file konfigurasi memiliki semua hardcoded sejauh apa subclass untuk tipe (antarmuka) yang akan disuntikkan selama waktu kompilasi. 

SUNTING 

Sebuah komentar yang bagus dari Jose Maria Arranz di DI

DI meningkatkan kohesi dengan menghilangkan kebutuhan untuk menentukan arah ketergantungan dan menulis kode lem.

Salah. Arah dependensi adalah dalam bentuk XML atau sebagai anotasi, dependensi Anda ditulis sebagai kode XML dan anotasi. XML dan anotasi ADALAH kode sumber.

DI mengurangi kopling dengan membuat semua komponen Anda menjadi modular (dapat diganti) dan memiliki antarmuka yang saling ditentukan dengan baik.

Salah. Anda tidak perlu kerangka DI untuk membangun kode modular berdasarkan antarmuka.

Tentang yang dapat diganti: dengan arsip .properties dan Class.forName yang sangat sederhana, Anda dapat menentukan yang dapat diubah oleh kelas. Jika kelas APAPUN kode Anda dapat diubah, Java bukan untuk Anda, gunakan bahasa scripting. Omong-omong: anotasi tidak dapat diubah tanpa kompilasi ulang.

Menurut pendapat saya ada satu-satunya alasan untuk kerangka kerja DI: pengurangan pelat ketel. Dengan sistem pabrik yang dilakukan dengan baik, Anda dapat melakukan hal yang sama, lebih terkontrol, dan lebih dapat diprediksi sebagai kerangka kerja DI pilihan Anda, kerangka kerja DI menjanjikan pengurangan kode (XML dan anotasi juga merupakan kode sumber). Masalahnya adalah pengurangan pelat ketel ini hanya nyata dalam kasus yang sangat sangat sederhana (satu instance-per kelas dan serupa), kadang-kadang di dunia nyata memilih objek layanan yang sesuai tidak semudah memetakan kelas ke objek tunggal.

10
Chookoos

Injeksi Ketergantungan berarti cara (sebenarnya cara apa pun) untuk satu bagian kode (misalnya kelas) untuk memiliki akses ke dependensi (bagian kode lain, misalnya kelas lain, tergantung pada) dalam cara modular tanpa hardcoded (sehingga dapat diubah atau diganti secara bebas, atau bahkan dimuat pada waktu lain, sesuai kebutuhan)

(dan ps, ya itu telah menjadi $ 25 nama yang terlalu hyped untuk konsep yang agak sederhana), .25 sen saya

8
Nikos M.

Saya tahu sudah ada banyak jawaban, tetapi saya menemukan ini sangat membantu: http://tutorials.jenkov.com/dependency-injection/index.html

Tidak Ada Ketergantungan:

public class MyDao {

  protected DataSource dataSource =
    new DataSourceImpl("driver", "url", "user", "password");

  //data access methods...
  public Person readPerson(int primaryKey) {...}

}

Ketergantungan:

public class MyDao {

  protected DataSource dataSource = null;

  public MyDao(String driver, String url, String user, String
 password){
    this.dataSource = new DataSourceImpl(driver, url, user, password);
  }

  //data access methods...
  public Person readPerson(int primaryKey)
  {...}

}

Perhatikan bagaimana instansasi DataSourceImpl dipindahkan ke konstruktor. Konstruktor mengambil empat parameter yang merupakan empat nilai yang dibutuhkan oleh DataSourceImpl. Meskipun kelas MyDao masih bergantung pada empat nilai ini, itu tidak lagi memenuhi dependensi itu sendiri. Mereka disediakan oleh kelas apa pun yang membuat instance MyDao.

7
Ali Issa

Jawaban populer tidak membantu, karena mereka mendefinisikan injeksi ketergantungan dengan cara yang tidak berguna. Mari kita sepakati bahwa dengan "ketergantungan" yang kita maksud adalah beberapa objek lain yang sudah ada sebelumnya yang dibutuhkan oleh objek X kita. Tapi kami tidak mengatakan kami melakukan "injeksi ketergantungan" ketika kami mengatakannya

$foo = Foo->new($bar);

Kami hanya memanggil parameter yang lewat ke konstruktor. Kami telah melakukan itu secara teratur sejak konstruktor ditemukan.

"Injeksi ketergantungan" dianggap sebagai jenis "inversi kontrol", yang berarti bahwa beberapa logika dikeluarkan dari pemanggil. Itu tidak terjadi ketika pemanggil melewati parameter, jadi jika itu DI, DI tidak akan menyiratkan inversi kontrol.

DI berarti ada tingkat menengah antara pemanggil dan konstruktor yang mengelola dependensi. Makefile adalah contoh sederhana injeksi ketergantungan. "Penelepon" adalah orang yang mengetik "make bar" pada baris perintah, dan "konstruktor" adalah kompiler. Makefile menentukan bahwa bilah bergantung pada foo, dan bilah

gcc -c foo.cpp; gcc -c bar.cpp

sebelum melakukan a

gcc foo.o bar.o -o bar

Orang yang mengetik "make bar" tidak perlu tahu bahwa bar tergantung pada foo. Ketergantungan disuntikkan antara "make bar" dan gcc.

Tujuan utama tingkat menengah bukan hanya untuk meneruskan dependensi ke konstruktor, tetapi untuk membuat daftar semua dependensi di hanya satu tempat , dan untuk menyembunyikannya dari koder (bukan untuk membuat koder menyediakannya) .

Biasanya tingkat menengah menyediakan pabrik untuk objek yang dibangun, yang harus memberikan peran yang harus dipenuhi oleh setiap jenis objek yang diminta. Itu karena dengan memiliki tingkat menengah yang menyembunyikan detail konstruksi, Anda sudah dikenai penalti abstraksi yang dikenakan oleh pabrik, jadi sebaiknya Anda menggunakan pabrik.

7
Phil Goetz

Injeksi ketergantungan adalah salah satu solusi yang memungkinkan untuk apa yang secara umum dapat disebut persyaratan "Ketergantungan Kebingungan". Dependency Obfuscation adalah metode untuk menghilangkan sifat 'jelas' dari proses penyediaan ketergantungan pada kelas yang membutuhkannya dan oleh karena itu mengaburkan, dalam beberapa cara, penyediaan ketergantungan tersebut kepada kelas tersebut. Ini belum tentu hal yang buruk. Pada kenyataannya, dengan mengaburkan cara dimana ketergantungan diberikan kepada kelas maka sesuatu di luar kelas bertanggung jawab untuk menciptakan ketergantungan yang berarti, dalam berbagai skenario, implementasi ketergantungan yang berbeda dapat dipasok ke kelas tanpa membuat perubahan apa pun. ke kelas. Ini bagus untuk beralih antara mode produksi dan pengujian (mis., Menggunakan ketergantungan layanan 'mock').

Sayangnya bagian yang buruk adalah bahwa beberapa orang berasumsi Anda memerlukan kerangka kerja khusus untuk melakukan kebingungan ketergantungan dan bahwa Anda entah bagaimana seorang programmer 'lebih rendah' ​​jika Anda memilih untuk tidak menggunakan kerangka kerja tertentu untuk melakukannya. Mitos lain yang sangat mengganggu, diyakini oleh banyak orang, adalah bahwa injeksi ketergantungan adalah satu-satunya cara untuk mencapai kebingungan ketergantungan. Ini terbukti dan historis dan jelas 100% salah, tetapi Anda akan kesulitan meyakinkan beberapa orang bahwa ada alternatif untuk injeksi ketergantungan untuk persyaratan kebingungan ketergantungan Anda.

Pemrogram telah memahami persyaratan kebingungan ketergantungan selama bertahun-tahun dan banyak solusi alternatif telah berkembang baik sebelum dan setelah injeksi ketergantungan disusun. Ada pola-pola Pabrik tetapi ada juga banyak opsi menggunakan ThreadLocal di mana tidak diperlukan injeksi ke instance tertentu - ketergantungan secara efektif disuntikkan ke dalam thread yang memiliki manfaat membuat objek tersedia (melalui metode pengambil statis yang mudah) untuk apa saja kelas yang membutuhkannya tanpa harus menambahkan anotasi ke kelas yang membutuhkannya dan mengatur 'lem' XML yang rumit untuk mewujudkannya. Ketika dependensi Anda diperlukan untuk kegigihan (JPA/JDO atau apa pun) itu memungkinkan Anda untuk mencapai 'kegigihan tranaparen' jauh lebih mudah dan dengan model domain dan kelas model bisnis yang dibuat murni dari POJO (mis. Tidak ada kerangka kerja spesifik/terkunci dalam anotasi).

6
Volksman

From the Book, ' Pengembang Java Beralasan Baik: Teknik vital pemrograman Java 7 dan polyglot

DI adalah bentuk khusus dari IoC, di mana proses menemukan dependensi Anda adalah di luar kendali langsung kode yang sedang Anda jalankan.

5
TastyCode

Dependency Injection (DI) adalah salah satu dari Pola Desain, yang menggunakan fitur dasar OOP - hubungan dalam satu objek dengan objek lain. Sementara warisan mewarisi satu objek untuk melakukan objek lain yang lebih kompleks dan spesifik, hubungan atau asosiasi hanya membuat pointer ke objek lain dari satu objek menggunakan atribut. Kekuatan DI dikombinasikan dengan fitur OOP lainnya seperti antarmuka dan kode sembunyi ..__ Misalkan, kami memiliki pelanggan (pelanggan) di perpustakaan, yang dapat meminjam hanya satu buku untuk kesederhanaan.

Antarmuka buku:

package com.deepam.hidden;

public interface BookInterface {

public BookInterface setHeight(int height);
public BookInterface setPages(int pages);   
public int getHeight();
public int getPages();  

public String toString();
}

Selanjutnya kita dapat memiliki banyak jenis buku; salah satu jenisnya adalah fiksi:

package com.deepam.hidden;

public class FictionBook implements BookInterface {
int height = 0; // height in cm
int pages = 0; // number of pages

/** constructor */
public FictionBook() {
    // TODO Auto-generated constructor stub
}

@Override
public FictionBook setHeight(int height) {
  this.height = height;
  return this;
}

@Override
public FictionBook setPages(int pages) {
  this.pages = pages;
  return this;      
}

@Override
public int getHeight() {
    // TODO Auto-generated method stub
    return height;
}

@Override
public int getPages() {
    // TODO Auto-generated method stub
    return pages;
}

@Override
public String toString(){
    return ("height: " + height + ", " + "pages: " + pages);
}
}

Sekarang pelanggan dapat memiliki hubungan dengan buku:

package com.deepam.hidden;

import Java.lang.reflect.Constructor;
import Java.lang.reflect.InvocationTargetException;

public class Subscriber {
BookInterface book;

/** constructor*/
public Subscriber() {
    // TODO Auto-generated constructor stub
}

// injection I
public void setBook(BookInterface book) {
    this.book = book;
}

// injection II
public BookInterface setBook(String bookName) {
    try {
        Class<?> cl = Class.forName(bookName);
        Constructor<?> constructor = cl.getConstructor(); // use it for parameters in constructor
        BookInterface book = (BookInterface) constructor.newInstance();
        //book = (BookInterface) Class.forName(bookName).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return book;
}

public BookInterface getBook() {
  return book;
}

public static void main(String[] args) {

}

}

Ketiga kelas dapat disembunyikan untuk implementasi itu sendiri. Sekarang kita dapat menggunakan kode ini untuk DI:

package com.deepam.implement;

import com.deepam.hidden.Subscriber;
import com.deepam.hidden.FictionBook;

public class CallHiddenImplBook {

public CallHiddenImplBook() {
    // TODO Auto-generated constructor stub
}

public void doIt() {
    Subscriber ab = new Subscriber();

    // injection I
    FictionBook bookI = new FictionBook();
    bookI.setHeight(30); // cm
    bookI.setPages(250);
    ab.setBook(bookI); // inject
    System.out.println("injection I " + ab.getBook().toString());

    // injection II
    FictionBook bookII = ((FictionBook) ab.setBook("com.deepam.hidden.FictionBook")).setHeight(5).setPages(108); // inject and set
    System.out.println("injection II " + ab.getBook().toString());      
}

public static void main(String[] args) {
    CallHiddenImplBook kh = new CallHiddenImplBook();
    kh.doIt();
}
}

Ada banyak cara berbeda cara menggunakan injeksi ketergantungan. Dimungkinkan untuk menggabungkannya dengan Singleton, dll., Tetapi pada dasarnya itu hanya asosiasi yang diwujudkan dengan membuat atribut tipe objek di dalam objek lain .Kegunaannya hanya dan hanya pada fitur, kode itu, yang harus kita tulis lagi dan lagi selalu disiapkan dan dilakukan untuk kita maju. Inilah sebabnya mengapa DI begitu terikat erat dengan Inversion of Control (IoC) yang berarti, bahwa program kami melewati kontrol modul berjalan lainnya, yang melakukan injeksi kacang ke kode kami. (Setiap objek, yang dapat disuntikkan dapat ditandatangani atau dianggap sebagai Bean.) Misalnya di Spring itu dilakukan dengan membuat dan inisialisasi ApplicationContext container, yang melakukan ini bekerja untuk kita. Kami hanya dalam kode kami membuat Konteks dan memohon inisialisasi kacang. Pada saat itu injeksi telah dilakukan secara otomatis.

4
hariprasad

dari Book Apress.Spring.Persistence.with.Hibernate.Oct.2010

Tujuan injeksi ketergantungan adalah untuk memisahkan pekerjaan menyelesaikan komponen perangkat lunak eksternal dari bisnis aplikasi Anda logika. Tanpa injeksi ketergantungan, perincian tentang bagaimana suatu komponen mengakses layanan yang diperlukan dapat kacau dengan komponen kode. Ini tidak hanya meningkatkan potensi kesalahan, menambahkan kode mengasapi, dan memperbesar kompleksitas perawatan; itu memasangkan komponen bersama-sama lebih dekat, sehingga sulit untuk memodifikasi dependensi ketika refactoring atau pengujian.

Sederhananya, dependensi injection (DI) adalah cara untuk menghilangkan dependensi atau ikatan erat antara objek yang berbeda. Dependency Injection memberikan perilaku kohesif untuk setiap objek. 

DI adalah implementasi prinsipal IOC dari Spring yang mengatakan "Jangan panggil kami, kami akan menghubungi Anda". Menggunakan programmer dependensi injeksi tidak perlu membuat objek menggunakan kata kunci baru. 

Objek pernah dimuat dalam wadah Spring dan kemudian kita menggunakannya kembali kapan pun kita membutuhkannya dengan mengambil objek-objek dari wadah Spring menggunakan metode getBean (String beanName).

3
Waqas Ahmed

Dependency Injection (DI) adalah bagian dari praktik Dependency Inversion Principle (DIP), yang juga disebut Inversion of Control (IoC). Pada dasarnya Anda perlu melakukan DIP karena Anda ingin membuat kode Anda lebih modular dan unit dapat diuji, bukan hanya satu sistem monolitik. Jadi Anda mulai mengidentifikasi bagian-bagian kode yang dapat dipisahkan dari kelas dan diabstraksi. Sekarang implementasi abstraksi perlu disuntikkan dari luar kelas. Biasanya ini dapat dilakukan melalui konstruktor. Jadi Anda membuat konstruktor yang menerima abstraksi sebagai parameter, dan ini disebut injeksi dependensi (via konstruktor). Untuk penjelasan lebih lanjut tentang wadah DIP, DI, dan IoC Anda dapat membaca Di sini

3

Ketergantungan injeksi adalah jantung dari konsep yang terkait dengan Kerangka Kerja Pegas. Sementara menciptakan kerangka kerja dari setiap pegas proyek dapat melakukan peran vital, dan di sini injeksi ketergantungan datang dengan kendi.

Sebenarnya, Misalkan di Jawa Anda membuat dua kelas yang berbeda sebagai kelas A dan kelas B, dan apa pun fungsi yang tersedia di kelas B yang ingin Anda gunakan di kelas A, Jadi pada saat itu injeksi ketergantungan dapat digunakan . Di mana Anda dapat objek peti dari satu kelas di kelas lain, dengan cara yang sama Anda dapat menyuntikkan seluruh kelas di kelas lain untuk membuatnya dapat diakses .. dengan cara ini ketergantungan dapat diatasi.

INJEKSI DEPENDENSI IS HANYA MENGGUNAKAN DUA KELAS DAN AT WAKTU YANG SAMA MENJAGA MEREKA TERPISAH.

3
mohit sarsar

Saya akan mengusulkan definisi yang sedikit berbeda, pendek dan tepat tentang apa itu Dependency Injection, dengan fokus pada tujuan utama, bukan pada cara teknis (mengikuti dari sini ):

Ketergantungan Injeksi adalah proses menciptakan statis, stateless grafik objek layanan, di mana setiap layanan ditentukan oleh ketergantungan.

Objek yang kita buat dalam aplikasi kita (terlepas dari apakah kita menggunakan Java, C # atau bahasa berorientasi objek lainnya) biasanya jatuh ke dalam salah satu dari dua kategori: "objek layanan" stateless, statis dan global (modul), dan stateful, dinamis dan lokal "Objek data".

Grafik modul - grafik objek layanan - biasanya dibuat pada saat startup aplikasi. Ini bisa dilakukan dengan menggunakan wadah, seperti Spring, tetapi juga bisa dilakukan secara manual, dengan mengirimkan parameter ke konstruktor objek. Kedua cara memiliki pro dan kontra, tetapi kerangka kerja jelas tidak diperlukan untuk menggunakan DI dalam aplikasi Anda.

Salah satu persyaratan adalah bahwa layanan harus ditentukan oleh dependensi mereka. Apa artinya ini sebenarnya tergantung pada bahasa dan pendekatan yang diambil dalam sistem yang diberikan. Biasanya, ini berbentuk parameter konstruktor, tetapi menggunakan setter juga merupakan pilihan. Ini juga berarti bahwa dependensi suatu layanan disembunyikan (ketika menggunakan metode layanan) dari pengguna layanan.

Kapan menggunakannya? Saya akan mengatakan setiap kali aplikasi cukup besar yang merangkum logika menjadi modul terpisah, dengan grafik dependensi antara modul memberikan keuntungan dalam keterbacaan dan explorability dari kode.

2
adamw

Dependency Injection adalah praktik untuk membuat agnostik komponen yang dipisahkan dari beberapa dependensinya, ini mengikuti pedoman SOLID yang mengatakan

Prinsip inversi ketergantungan: seseorang harus "bergantung pada abstraksi, .__ bukan konkret.

Implementasi Dependency Injection yang lebih baik adalah pola desain Root Komposisi, karena memungkinkan komponen Anda dipisahkan dari wadah injeksi dependensi.

Saya merekomendasikan artikel hebat ini tentang Komposisi Root http://blog.ploeh.dk/2011/07/28/CompositionRoot/ .__ ditulis oleh Mark Seemann

di sini adalah poin penting dari artikel ini:

Root Komposisi adalah (lebih disukai) lokasi unik dalam aplikasi di mana modul disusun bersama.

...

Hanya aplikasi yang harus memiliki Root Komposisi. Perpustakaan dan kerangka kerja seharusnya tidak.

...

Wadah DI hanya boleh dirujuk dari Root Komposisi . Semua modul lain seharusnya tidak memiliki referensi ke wadah.

Dokumentasi Di-Ninja, kerangka kerja injeksi ketergantungan, adalah contoh yang sangat baik untuk menunjukkan cara kerja prinsip-prinsip Komposisi Root dan Ketergantungan Injeksi . https://github.com/di-ninja/di-ninja Seperti yang saya tahu, adalah satu-satunya DiC dalam javascript yang menerapkan pola desain Composition-Root.

1
Jo Takion

Dari Christoffer Noring, buku Pablo Deeleman "Learning Angular - Second Edition":

"Ketika aplikasi kita tumbuh dan berkembang, masing-masing entitas kode kita secara internal akan membutuhkan instance dari objek lain, yang lebih dikenal sebagai dependensi dalam dunia rekayasa perangkat lunak. Tindakan meneruskan dependensi tersebut kepada klien dependen dikenal sebagai injeksi, dan itu juga memerlukan partisipasi dari entitas kode lain, bernama injector. injector akan bertanggung jawab untuk instantiating dan bootstrap dependensi yang diperlukan sehingga mereka siap untuk digunakan sejak saat mereka berhasil disuntikkan ke klien. Ini sangat penting karena klien tidak tahu apa-apa tentang instantiate dependensinya sendiri dan hanya mengetahui antarmuka yang mereka implementasikan untuk menggunakannya. "

1
H S Progr

Injeksi Ketergantungan adalah jenis implementasi prinsip " Inversion of Control " yang menjadi dasar pembangunan Kerangka Kerja.

Kerangka Kerja sebagaimana dinyatakan dalam "Pola Desain" dari GoF adalah kelas yang menerapkan logika aliran kontrol utama yang meningkatkan pengembang untuk melakukan itu, dengan cara ini Kerangka mewujudkan pembalikan prinsip kontrol.

Cara untuk menerapkan sebagai teknik, dan bukan sebagai hierarki kelas, prinsip IoC ini hanyalah Injeksi Ketergantungan.

DIsebagian besar terdiri dari mendelegasikan pemetaan instance kelas dan tipe referensi untuk instance tersebut, ke "entitas" eksternal: objek, kelas statis, komponen, kerangka kerja, dll ... 

Kelas instance adalah "dependencies", pengikatan eksternal komponen panggilan dengan instance kelas melalui referensi itu adalah "injeksi".

Jelas Anda dapat menerapkan teknik ini dengan berbagai cara seperti yang Anda inginkan dari sudut pandang OOP, lihat misalnya injeksi konstruktor, injeksi setter, injeksi antarmuka.

Mendelegasikan pihak ketiga untuk melaksanakan tugas mencocokkan referensi ke suatu objek sangat berguna ketika Anda ingin memisahkan sepenuhnya komponen yang memerlukan beberapa layanan dari implementasi layanan yang sama. 

Dengan cara ini, ketika mendesain komponen, Anda dapat fokus secara eksklusif pada arsitektur dan logika spesifiknya, mempercayai antarmuka untuk berkolaborasi dengan objek lain tanpa khawatir tentang segala jenis perubahan implementasi objek/layanan yang digunakan, juga jika objek yang sama yang Anda gunakan akan sepenuhnya diganti (jelas menghormati antarmuka).

1
Ciro Corvino

Setiap aplikasi nontrivial terdiri dari dua atau lebih kelas yang saling berkolaborasi untuk melakukan beberapa logika bisnis. Secara tradisional, setiap objek bertanggung jawab untuk mendapatkan referensi sendiri ke objek yang dikolaborasikan dengannya (dependensinya). Ketika menerapkan DI, objek diberi dependensinya pada waktu pembuatan oleh beberapa entitas eksternal yang mengoordinasikan setiap objek dalam sistem. Dengan kata lain, dependensi disuntikkan ke objek.

Untuk perincian lebih lanjut silakan lihat masukkan deskripsi tautan di sini

0
Hisham Javed

DI adalah bagaimana benda-benda nyata benar-benar berinteraksi satu sama lain tanpa satu objek yang bertanggung jawab atas keberadaan objek lain. Objek harus diperlakukan secara setara. Mereka semua objek. Tidak seorang pun harus bertindak seperti pencipta. Ini adalah bagaimana Anda melakukan keadilan pada objek Anda.

Contoh sederhana

jika Anda memerlukan dokter, Anda cukup pergi dan mencari (yang sudah ada). Anda tidak akan berpikir untuk membuat dokter dari awal untuk membantu Anda. Dia sudah ada dan dia bisa melayani Anda atau benda lain. Dia memiliki hak untuk hidup apakah Anda (satu objek) membutuhkannya atau tidak karena tujuannya adalah untuk melayani satu atau lebih objek. Yang memutuskan keberadaannya adalah Tuhan Yang Mahakuasa, bukan seleksi alam. Oleh karena itu, salah satu keuntungan DI adalah menghindari membuat benda-benda berlebihan yang tidak berguna yang hidup tanpa tujuan selama masa hidup semesta Anda (mis. Aplikasi).

0
Shadi Namrouti