Ada kerangka kerja yang saya bantu desain. Ada beberapa tugas umum yang harus dilakukan dengan menggunakan beberapa komponen umum: Logging, Caching dan meningkatkan peristiwa pada khususnya.
Saya tidak yakin apakah lebih baik menggunakan injeksi ketergantungan dan memperkenalkan semua komponen ini ke setiap layanan (seperti properti misalnya) atau haruskah saya menempatkan beberapa jenis meta data pada setiap metode layanan saya dan menggunakan intersepsi untuk melakukan tugas-tugas umum ini ?
Berikut ini contoh keduanya:
Injeksi:
public class MyService
{
public ILoggingService Logger { get; set; }
public IEventBroker EventBroker { get; set; }
public ICacheService Cache { get; set; }
public void DoSomething()
{
Logger.Log(myMessage);
EventBroker.Publish<EventType>();
Cache.Add(myObject);
}
}
dan inilah versi lainnya:
Penangkapan:
public class MyService
{
[Log("My message")]
[PublishEvent(typeof(EventType))]
public void DoSomething()
{
}
}
Ini pertanyaan saya:
- Solusi mana yang terbaik untuk kerangka kerja yang rumit?
- Jika intersepsi menang, apa opsi saya untuk berinteraksi dengan nilai internal suatu metode (misalnya untuk digunakan dengan layanan cache?)? Bisakah saya menggunakan cara lain daripada atribut untuk menerapkan perilaku ini?
- Atau mungkin ada solusi lain untuk menyelesaikan masalah?
c#
dependency-injection
Beatles1692
sumber
sumber
Jawaban:
Masalah lintas sektoral seperti logging, caching dll. Bukan ketergantungan, jadi jangan disuntikkan ke layanan. Namun, sementara kebanyakan orang tampaknya meraih kerangka kerja AOP penuh interleaving, ada pola desain yang bagus untuk ini: Dekorator .
Pada contoh di atas, biarkan MyService mengimplementasikan antarmuka IMyService:
Ini membuat kelas MyService benar-benar bebas dari Masalah Lintas Sektor, sehingga mengikuti Prinsip Tanggung Jawab Tunggal (SRP).
Untuk menerapkan logging, Anda dapat menambahkan Decorator logging:
Anda dapat menerapkan caching, pengukuran, acara, dll. Dengan cara yang sama. Setiap Dekorator melakukan tepat satu hal, sehingga mereka juga mengikuti SRP, dan Anda dapat menyusunnya dengan cara yang rumit dan sewenang-wenang. Misalnya
sumber
Untuk beberapa layanan, saya pikir jawaban Mark baik: Anda tidak perlu belajar atau memperkenalkan dependensi pihak ketiga yang baru dan Anda masih akan mengikuti prinsip-prinsip SOLID yang baik.
Untuk sejumlah besar layanan, saya akan merekomendasikan alat AOP seperti PostSharp atau Castle DynamicProxy. PostSharp memiliki versi gratis (seperti bir), dan mereka baru-baru ini merilis PostSharp Toolkit untuk Diagnostik , (gratis seperti dalam bir DAN pidato) yang akan memberi Anda beberapa fitur logging di luar kotak.
sumber
Saya menemukan desain kerangka kerja sebagian besar ortogonal untuk pertanyaan ini - Anda harus fokus pada antarmuka kerangka kerja Anda terlebih dahulu, dan mungkin sebagai latar belakang proses mental mempertimbangkan bagaimana seseorang mungkin benar-benar mengkonsumsinya. Anda tidak ingin melakukan sesuatu yang mencegahnya digunakan dengan cara yang cerdik, tetapi seharusnya hanya menjadi input ke dalam desain kerangka kerja Anda; satu di antara banyak.
sumber
Saya sering menghadapi masalah ini dan saya pikir saya telah menemukan solusi sederhana.
Awalnya saya pergi dengan pola dekorator dan secara manual menerapkan setiap metode, ketika Anda memiliki ratusan metode ini menjadi sangat membosankan.
Saya kemudian memutuskan untuk menggunakan PostSharp tetapi saya tidak suka gagasan menyertakan seluruh perpustakaan hanya untuk melakukan sesuatu yang dapat saya capai dengan (banyak) kode sederhana.
Saya kemudian pergi melalui rute proksi transparan yang menyenangkan tetapi melibatkan memancarkan IL secara dinamis pada waktu berjalan dan tidak akan menjadi sesuatu yang ingin saya lakukan dalam lingkungan produksi.
Saya baru-baru ini memutuskan untuk menggunakan template T4 untuk secara otomatis menerapkan pola dekorator pada waktu desain, ternyata template T4 sebenarnya cukup sulit untuk dikerjakan dan saya membutuhkan ini dilakukan dengan cepat sehingga saya membuat kode di bawah ini. Cepat dan kotor (dan itu tidak mendukung properti) tetapi mudah-mudahan seseorang akan merasakan manfaatnya.
Ini kodenya:
Berikut ini sebuah contoh:
Kemudian buat kelas yang disebut LoggingTestAdapter yang mengimplementasikan ITestAdapter, dapatkan visual studio untuk secara otomatis mengimplementasikan semua metode dan kemudian jalankan melalui kode di atas. Anda kemudian harus memiliki sesuatu seperti ini:
Ini dia dengan kode pendukung:
sumber