Saya bertanya-tanya bagaimana cara mengelompokkan repositori saya? Seperti dari contoh yang saya lihat di asp.net MVC dan di buku saya, mereka pada dasarnya menggunakan satu repositori per tabel database. Tapi sepertinya banyak repositori yang membuat Anda harus memanggil banyak repositori nanti untuk mengejek dan semacamnya.
Jadi saya rasa saya harus mengelompokkan mereka. Namun saya tidak yakin bagaimana mengelompokkan mereka.
Sekarang saya membuat Repositori pendaftaran untuk menangani semua hal pendaftaran saya. Namun ada 4 tabel yang perlu saya perbarui dan sebelumnya saya memiliki 3 repositori untuk melakukan ini.
Misalnya salah satu tabel adalah tabel lisensi. Ketika mereka mendaftar, saya melihat kunci mereka dan memeriksanya untuk melihat apakah ada di database. Sekarang apa yang terjadi jika saya perlu memeriksa kunci lisensi ini atau sesuatu yang lain dari tabel itu di tempat lain selain pendaftaran?
Satu tempat bisa login (periksa apakah kuncinya tidak kedaluwarsa).
Jadi apa yang akan saya lakukan dalam situasi ini? Tulis ulang kode itu lagi (pecahkan KERING)? Cobalah untuk menggabungkan 2 repositori ini bersama-sama dan berharap tidak ada metode yang diperlukan di waktu lain (seperti mungkin saya mungkin memiliki metode yang memeriksa apakah userName digunakan - mungkin saya akan membutuhkannya di tempat lain).
Juga jika saya menggabungkan mereka bersama-sama saya akan membutuhkan 2 lapisan layanan pergi ke repositori yang sama karena saya pikir memiliki semua logika untuk 2 bagian situs yang berbeda akan panjang dan saya harus memiliki nama seperti ValidateLogin (), ValdiateRegistrationForm () , ValdiateLoginRetrievePassword (), dll.
Atau panggil Repositori dan hanya memiliki nama yang terdengar aneh?
Sepertinya sulit untuk membuat repositori yang memiliki nama yang cukup umum sehingga Anda dapat menggunakannya untuk banyak tempat di aplikasi Anda dan masih masuk akal dan saya rasa memanggil repositori lain dalam repositori tidak akan menjadi praktik yang baik?
sumber
Jawaban:
Satu hal yang saya lakukan salah saat bermain-main dengan pola repositori - sama seperti Anda, saya pikir tabel itu terkait dengan repositori 1: 1. Saat kami menerapkan beberapa aturan dari Domain Driven Design - masalah pengelompokan repositori sering kali hilang.
Repositori harus per akar Agregat dan bukan tabel. Artinya - jika entitas tidak boleh hidup sendiri (yaitu - jika Anda memiliki
Registrant
yang berpartisipasi secara khususRegistration
) - itu hanya sebuah entitas, itu tidak memerlukan repositori, itu harus diperbarui / dibuat / diambil melalui repositori root agregat itu milik.Tentu saja - dalam banyak kasus, teknik pengurangan jumlah repositori ini (sebenarnya - ini lebih merupakan teknik untuk menyusun model domain Anda) tidak dapat diterapkan karena setiap entitas seharusnya menjadi akar gabungan (yang sangat bergantung pada domain Anda, Saya hanya bisa memberikan tebakan buta). Dalam contoh Anda -
License
tampaknya menjadi akar agregat karena Anda harus dapat memeriksanya tanpa konteksRegistration
entitas.Tapi itu tidak membatasi kita pada repositori bertingkat (
Registration
repositori diperbolehkan untuk mereferensikanLicense
repositori jika diperlukan). Itu tidak membatasi kita untuk mereferensikanLicense
repositori (lebih disukai - melalui IoC) langsung dariRegistration
objek.Cobalah untuk tidak mengarahkan desain Anda melalui komplikasi yang disebabkan oleh teknologi atau kesalahpahaman tentang sesuatu. Mengelompokkan repositori
ServiceX
hanya karena Anda tidak ingin membangun 2 repositori bukanlah ide yang baik.Jauh lebih baik untuk memberinya nama yang tepat -
RegistrationService
yaituTetapi layanan harus dihindari secara umum - mereka sering menjadi penyebab yang mengarah pada model domain anemia .
EDIT:
Mulailah menggunakan IoC. Ini benar-benar meringankan rasa sakit ketergantungan suntikan.
Alih-alih menulis:
var registrationService = new RegistrationService(new RegistrationRepository(), new LicenseRepository(), new GodOnlyKnowsWhatElseThatServiceNeeds());
Anda akan bisa menulis:
var registrationService = IoC.Resolve<IRegistrationService>();
Ps Akan lebih baik menggunakan apa yang disebut pencari layanan umum tetapi itu hanya sebuah contoh.
sumber
Satu hal yang saya mulai lakukan untuk mengatasi ini adalah benar-benar mengembangkan layanan yang membungkus repositori N. Semoga kerangka kerja DI atau IoC Anda dapat membantu mempermudahnya.
public class ServiceImpl { public ServiceImpl(IRepo1 repo1, IRepo2 repo2...) { } }
Apakah itu masuk akal? Juga, saya memahami bahwa berbicara tentang layanan di rumah ini mungkin atau mungkin tidak benar-benar sesuai dengan prinsip DDD, saya hanya melakukannya karena tampaknya berhasil.
sumber
Apa yang saya lakukan adalah saya memiliki kelas dasar abstrak yang didefinisikan sebagai berikut:
public abstract class ReadOnlyRepository<T,V> { V Find(T lookupKey); } public abstract class InsertRepository<T> { void Add(T entityToSave); } public abstract class UpdateRepository<T,V> { V Update(T entityToUpdate); } public abstract class DeleteRepository<T> { void Delete(T entityToDelete); }
Anda kemudian dapat menurunkan repositori Anda dari kelas dasar abstrak dan memperluas repositori tunggal Anda selama argumen umum berbeda misalnya;
public class RegistrationRepository: ReadOnlyRepository<int, IRegistrationItem>, ReadOnlyRepository<string, IRegistrationItem>
dll ....
Saya memerlukan repositori terpisah karena kami memiliki batasan pada beberapa repositori kami dan ini memberi kami fleksibilitas maksimum. Semoga ini membantu.
sumber
Saya memiliki ini sebagai kelas repositori saya dan ya saya memperluas di repositori tabel / area tetapi terkadang saya masih harus istirahat KERING.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MvcRepository { public class Repository<T> : IRepository<T> where T : class { protected System.Data.Linq.DataContext _dataContextFactory; public IQueryable<T> All() { return GetTable.AsQueryable(); } public IQueryable<T> FindAll(Func<T, bool> exp) { return GetTable.Where<T>(exp).AsQueryable(); } public T Single(Func<T, bool> exp) { return GetTable.Single(exp); } public virtual void MarkForDeletion(T entity) { _dataContextFactory.GetTable<T>().DeleteOnSubmit(entity); } public virtual T CreateInstance() { T entity = Activator.CreateInstance<T>(); GetTable.InsertOnSubmit(entity); return entity; } public void SaveAll() { _dataContextFactory.SubmitChanges(); } public Repository(System.Data.Linq.DataContext dataContextFactory) { _dataContextFactory = dataContextFactory; } public System.Data.Linq.Table<T> GetTable { get { return _dataContextFactory.GetTable<T>(); } } } }
EDIT
public class AdminRepository<T> : Repository<T> where T: class { static AdminDataContext dc = new AdminDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["MY_ConnectionString"].ConnectionString); public AdminRepository() : base( dc ) { }
Saya juga memiliki datacontext yang dibuat menggunakan kelas Linq2SQL.dbml.
Jadi sekarang saya memiliki repositori standar yang mengimplementasikan panggilan standar seperti All and Find dan di AdminRepository saya, saya memiliki panggilan khusus.
Tidak menjawab pertanyaan KERING meskipun saya tidak berpikir.
sumber
Berikut adalah contoh implementasi Repositori generik menggunakan FluentNHibernate. Ia mampu mempertahankan semua kelas yang telah Anda tulis mapper untuk. Ia bahkan mampu menghasilkan database Anda berdasarkan kelas mapper.
sumber
Pola Repositori adalah pola desain yang buruk. Saya bekerja dengan banyak proyek .Net lama dan pola ini biasanya menyebabkan kesalahan "Transaksi Terdistribusi", "Kembalikan Sebagian", dan "Kumpulan Koneksi Habis" yang dapat dihindari. Masalahnya adalah bahwa pola mencoba menangani koneksi dan transaksi secara internal tetapi itu harus ditangani di lapisan Pengontrol. Juga EntityFramework sudah mengabstraksi banyak logika. Saya akan menyarankan menggunakan pola Layanan alih-alih menggunakan kembali kode bersama.
sumber
Saya menyarankan Anda untuk melihat Arsitektur Sharp . Mereka menyarankan menggunakan satu repositori per entitas. Saya menggunakannya saat ini dalam proyek saya dan sangat senang dengan hasilnya.
sumber