Ketergantungan Injeksi dan Singleton. Apakah mereka dua konsep yang sama sekali berbeda?

17

Saya telah mendengar tentang menggunakan injeksi ketergantungan pada Singleton untuk kolega saya. Saya masih tidak bisa melihat apakah itu dua pola ortogonal yang dapat diganti satu sama lain? Atau apakah DI merupakan metode untuk membuat pola Singleton teruji?

Silakan lihat potongan kode berikut.

    IMathFace obj = Singleton.Instance;

    SingletonConsumer singConsumer = new SingletonConsumer(obj);

    singConsumer.ConsumerAdd(10,20);

Ini SingletonConsumermenerima parameter tipe IMathFace. Alih-alih mengakses kelas singleton secara internal, SingletonConsumerakan mendapatkan instance singleton dilewatkan oleh penelepon. Apakah ini contoh yang baik dari mengkonsumsi kelas tunggal melalui injeksi ketergantungan?

logeeks
sumber
Bisakah Anda memberi tahu saya bagaimana DI dapat menggantikan singleton?
7
Singleton adalah pola desain. DI / IoC adalah teknik.
Dave
2
DI tidak dapat menggantikan Singleton seperti pisang dapat menggantikan karburator. Mereka konsep yang sama sekali berbeda.
Dave
jadi contoh saya valid.
1
Ya, tapi itu bisa dilakukan dengan mengorbankan enkapsulasi (yang juga berlaku untuk non-tunggal) lihat: stackoverflow.com/questions/1005473/…

Jawaban:

17

Saya pikir dia bermaksud bahwa Anda harus menggunakan injeksi ketergantungan untuk menyuntikkan satu contoh layanan, daripada menggunakan implementasi Singleton klasik dengan pengakses statis MySingleton.Instance.

public class MySingleton
{
    public static MySingleton Instance{get{...}};
}

Dengan implementasi singleton klasik semua kode Anda bergantung pada layanan yang menjadi singleton. Anda pada dasarnya hardcode asumsi itu menjadi mengkonsumsi kode setiap kali Anda gunakan MySingleton.Instance.

Di sisi lain dengan DI Anda mendapatkan contoh layanan yang diteruskan ke konstruktor Anda, dan menyimpannya. Yang ada hanya satu contoh layanan ini adalah detail implementasi. Anda dapat dengan mudah mengubahnya untuk memberikan kode konsumsi contoh berbeda. Dengan begitu Anda memiliki beberapa kelas / antarmuka yang kebetulan diimplementasikan oleh satu instance, bukannya memaksakan bahwa hanya ada satu instance.

Ini berguna jika Anda misalnya menginginkan implementasi tiruan dari layanan untuk pengujian, atau jika bagian-bagian berbeda dari program memerlukan konfigurasi layanan yang berbeda.

CodesInChaos
sumber
4

Ya kamu benar. Alih-alih mengakses objek melalui singleton, Anda memberikan referensi padanya sehingga Anda menggunakan injeksi konstruktor.

Apa yang orang lain tunjukkan adalah bahwa pengertian ini tidak berhubungan. Mengonsumsi contoh tunggal bukan hal yang istimewa karena objek yang Anda injeksi tidak terlalu peduli dari mana objek yang disuntikkan berasal.

Wiktor Zychla
sumber
2

Ada satu kasus di mana pola Singleton dan DI / IoC berpotongan - injeksi Singleton.

Kebanyakan kerangka kerja DI dapat dikonfigurasikan untuk membuat instance dari objek yang disuntikkan. Setiap objek konsumen yang meminta instance dari objek seperti itu akan mendapatkan instance tunggal yang sama. Contoh itu menurut definisi adalah Singleton. Itu saja untuk konsep yang tumpang tindih.

Dave
sumber
1

Kebingungan di sini adalah bahwa dua konsep telah digabungkan: singleton dan accessor / gateway statis ke instance singleton.

Seperti yang telah Anda identifikasi dengan benar, kolega Anda menyarankan agar ketergantungan disuntikkan daripada diakses secara langsung menggunakan Singleton.Instance(gateway statis).

Alasan bahwa ini tidak ada hubungannya dengan pola singleton adalah bahwa konsep DI yang sama berlaku sama untuk instantiating objek non-singleton new Foo(). Ketergantungan akan disuntikkan terlepas dari apakah itu merupakan implementasi tunggal.

Jay
sumber