Bagaimana injeksi ketergantungan dapat diintegrasikan ke dalam bahasa? [Tutup]

10

Saya telah berpikir sedikit tentang bagaimana injeksi ketergantungan dapat lebih baik diintegrasikan secara langsung ke dalam bahasa seperti C #. Saya telah menemukan solusi potensial yang ingin saya dengar pendapat Anda. Saya belum pernah menggunakan banyak kerangka kerja injeksi ketergantungan sehingga mungkin ada sesuatu yang saya abaikan

Bagaimanapun, idenya adalah untuk dapat mendeklarasikan properti sebagai "dapat disuntikkan" menggunakan kata kunci. Ketika sebuah objek dipakai, dan properti itu tidak diinisialisasi melalui konstruktor, atau penginisialisasi objek, ia meminta instance dari tipe properti itu dari beberapa layanan global.

Demikian pula Anda mendaftarkan penangan untuk jenis yang berbeda ke layanan itu sehingga Anda dapat instantiate jenis properti yang diinjeksi.

Keuntungan menggunakan jenis arsitektur IMO ini adalah ia cukup fleksibel dan mudah digunakan. The downside adalah bahwa mungkin ada beberapa overhead melakukan panggilan ke singleton setiap kali Anda memulai kelas yang memiliki suntikan.

Kemudian lagi itu hanya masalah untuk kelas yang sering dipakai dalam solusi kinerja tinggi sehingga seharusnya tidak menjadi masalah. Mungkin Anda bisa menggunakan semacam pabrik dalam hal itu.

Pikiran, masalah, pertanyaan, ide yang lebih baik?

Kode

public class SomeClass
{

  public SomeClass()
  {
     //implicit behavior if Animal is not set in constructor or initializer
    this.Animal =  GlobalInjector.Get(this,typeof(Mammal))

  }

  public injectable Mammal Animal  
  {
   get;
   set;
  }
}


 GlobalInjector.Register(typeof(Mammal), () => return new Mammal(someParameter));
Homde
sumber
Bisakah Anda memberikan contoh kode pseudo bagi kita yang tidak terbiasa dengan DI? PS. Mungkin Anda bisa menjawab pertanyaan saya tentang DI juga? :)
Steven
2
Saya tidak yakin saya mengerti. Anda bisa mendapatkan semua itu dengan wadah DI global dan atribut '[Suntik]' bukan kata kunci, kan?
nikie
Hai, saya mencoba menulis sedikit tentang DI pada pertanyaan Anda, tidak yakin itu menjawabnya
Homde
nikie: Ya tentu, saya kira Anda bisa menerapkan mekanisme yang sebenarnya dengan cara yang berbeda, saya lebih tertarik jika logika yang mendasarinya adalah suara
Homde
Jadi apa yang berbeda antara ini dan IoC yang ada selain kata kunci tambahan Anda?
Matthew Whited

Jawaban:

7

Ada hal-hal yang termasuk dalam bahasa, dan hal-hal yang tidak. Dulu C mengakui bahwa IO tidak termasuk dalam bahasa karena itu eksternal untuk model komputasi dan dapat diimplementasikan dengan perpustakaan fungsi.

Ketergantungan Injeksi adalah seperti itu. Ini eksternal untuk bahasa dan dapat diimplementasikan dengan kerangka kerja yang sesuai.

Salah satu masalah dengan bahasa modern adalah mereka mencoba melakukan terlalu banyak. Akhirnya bahasa-bahasa itu runtuh karena bobotnya sendiri ketika programmer melarikan diri ke bahasa yang lebih sederhana.

Paman Bob.
sumber
Saya setuju secara teori, Anda tidak dapat memiliki bahasa di mana setiap fungsi adalah fitur dari bahasa tanpa membengkak. Namun selalu ada ruang untuk abstraksi baru yang lebih tinggi yang membantu kami menulis kode yang lebih baik. Mungkin injeksi dependensi semata bukanlah masalah yang perlu dipecahkan tetapi masalah yang diatasi, yaitu cara untuk memudahkan kita mengurangi ketergantungan. Ini mungkin bukan cara terbaik untuk melakukannya :)
Homde
5

Itu tidak diperlukan

Salah satu hal yang paling saya sukai tentang kerangka kerja DI terbaik yang saya gunakan adalah bahwa kode konfigurasi tingkat atas adalah satu-satunya bagian dari kode Anda yang perlu diketahui tentang DI. Pengkabelan otomatis dilakukan pada tingkat wadah dan konfigurasi / "memuat modul", dan kode aplikasi Anda dapat sepenuhnya tidak menyadarinya.

Ini berarti tidak ada atribut, tidak ada string sihir, tidak ada konvensi. Setiap bagian dari kode hanya tahu bahwa ia menerima kode dalam konstruktornya (/ properties / methods), dan itu saja.

Dengan desain seperti itu Anda tidak perlu mengubah bahasa sama sekali untuk mendukung Dependency Injection.

Ini berpotensi berbahaya

Hal yang paling saya takuti tentang sistem injeksi ketergantungan terintegrasi bahasa adalah bahwa ia akan meningkatkan penghalang terhadap implementasi lainnya, namun mungkin akan melukis dirinya sendiri ke sudut dalam beberapa aspek.

Beberapa cara itu bisa melukis dirinya sendiri ke sudut:

  • Hanya mendukung konfigurasi berbasis XML, atau hanya konfigurasi berbasis kode
  • Tidak dapat mendukung pola desain Pabrik secara bersih (bukan hanya komponen sementara: komponen yang dihasilkan saat berjalan)
  • Entah bagaimana mengubah kode saya jadi saya terpaksa menggunakan injeksi dependensi, dan tidak bisa begitu saja membuat kelas saya untuk tes unit
  • Tidak mendukung siklus kustom
  • Tidak bisa diperluas
  • Tidak dapat diganti dalam kasus di mana saya membutuhkan penyesuaian yang lebih besar
  • Menjadi rusak dalam beberapa hal yang belum kita pahami, karena kita. Pengguna net belum menggunakan DI cukup lama untuk mengetahui jebakan
Merlyn Morgan-Graham
sumber
4

Pernahkah Anda melihat Framework Extensibility Managed yang datang dengan .NET 4? Inilah artikel yang saya tulis dengan beberapa contoh. Pada dasarnya ini adalah bentuk injeksi ketergantungan yang dibangun ke dalam .NET, dengan fitur tambahan run-time dapat ditemukan.

Suntikan properti terlihat seperti ini:

class Program
{
    [Import]
    public IMessageSender MessageSender { get; set; }
}

Suntikan konstruktor terlihat seperti ini:

class Program
{
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    ...
    }
}

Anda dapat mengimpor bidang, melakukan impor opsional, mengimpor koleksi layanan, termasuk melakukan malas mengimpor dengan metadata sehingga Anda dapat mencari layanan yang sesuai untuk instantiate. Anda bahkan dapat mengimpor kembali saat runtime untuk mencari ekstensi baru.

Scott Whitlock
sumber
Sementara MEF benar-benar keren untuk hal-hal plugin saya tidak berpikir saya ingin menggunakannya sebagai mekanisme DI umum
Homde
1
@ MKO - Bisakah Anda menguraikan apa yang hilang? Saya mengetahui semua artikel di mana Glenn Block berlomba untuk meyakinkan orang bahwa MEF tidak keluar untuk menggantikan semua kerangka kerja DI, tetapi jika Anda melihat detailnya, jelas itu lebih merupakan pernyataan politik daripada yang lainnya. Namun, jika Anda dapat memberikan daftar fitur yang kurang MEF dibandingkan dengan kerangka kerja DI lainnya, itu akan membantu orang membuat keputusan. Selain itu, pertanyaannya adalah tentang kerangka kerja DI di C #, dan MEF jelas wadah DI dalam kerangka NET.
Scott Whitlock
2
  1. Anda tidak benar-benar menggambarkan mekanisme konfigurasi, yang IMHO adalah bagian yang sulit. Bagaimana Anda membuat semua kode berjalan di satu utas menggunakan DB-koneksi A, und semua kode di utas lain sambungan B? Bagaimana Anda memblokir injeksi sumber daya tertentu, karena pengguna yang saat ini masuk tidak diizinkan untuk mengaksesnya?
  2. Jangan gunakan injektor global. Jangan menggunakan hal global sama sekali, atau Anda mungkin juga menggunakan variabel global. Tidak, menggunakan OOP-speak seperti singleton atau "static" bukannya global tidak mengubah sifat global mereka.
  3. Pertimbangkan wadah dengan cakupan dinamis. Sementara pelingkupan leksikal seharusnya menang melawan pelingkupan dinamis, saya percaya bahwa ruang lingkup dinamis akan menjadi pengganti yang baik untuk ruang lingkup global. Warisan diferensial akan menjadi implementasi yang bagus (seperti pada pewarisan berbasis prototipe).
  4. Saya percaya bahwa mekanisme DI-mandat bahasa harus benar-benar sederhana, tidak ada hal-hal perusahaan yang merupakan norma dalam C # dan Java. Mekanisme pelingkupan dinamis dengan lapisan konfigurasi sederhana di atas mungkin dapat melakukan trik. Solusi enterprisey dapat dilapisi oleh pihak ketiga.
Waquo
sumber