Her şeyden önce, bazı cevapların önerdiği gibi, EF'in kendisi bir depo modelidir, sadece onu depo olarak adlandırmak için daha fazla soyutlama oluşturmaya gerek yoktur.
Birim Testleri için Mockable Depo, gerçekten buna ihtiyacımız var mı?
İş mantığımızı doğrudan SQL test DB'sine karşı test etmek için EF'in birim testlerinde DB'yi test etmesine izin verdik. Herhangi bir depo modeline sahip olmanın hiçbir faydası görmüyorum. Test veritabanına karşı birim testleri yapmak gerçekten yanlış olan nedir? Toplu işlemler mümkün olmadığı için ham SQL yazıyoruz. Bellekteki SQLite, gerçek veritabanına karşı birim testleri yapmak için mükemmel bir adaydır.
Gereksiz Soyutlama
Gelecekte EF'yi NHbibernate vb. Veya başka bir şeyle kolayca değiştirebilmeniz için depo oluşturmak ister misiniz? Harika bir plan gibi görünüyor, ancak gerçekten uygun maliyetli mi?
Linq birim testlerini mi öldürüyor?
Nasıl öldürebileceğine dair herhangi bir örnek görmek isterim.
Bağımlılık Enjeksiyonu, IoC
Vay canına, bunlar harika kelimeler, elbette teoride harika görünüyorlar, ancak bazen harika tasarım ile harika çözüm arasında bir tercih yapmak zorunda kalıyorsunuz. Bunların hepsini kullandık ve sonunda hepsini çöpe atıp farklı bir yaklaşım seçtik. Boyuta Karşı Hıza (Kodun boyutu ve Geliştirme hızı) gerçek hayatta çok önemlidir. Kullanıcılar esnekliğe ihtiyaç duyar, kodunuzun DI veya IoC açısından tasarım açısından harika olup olmadığını umursamazlar.
Visual Studio oluşturmadığınız sürece
Visual Studio veya Eclipse gibi birçok kişi tarafından geliştirilecek karmaşık bir program oluşturuyorsanız ve oldukça özelleştirilebilir olması gerekiyorsa, tüm bu harika tasarımlara ihtiyaç vardır. Tüm büyük geliştirme modelleri, bu IDE'lerin yıllarca geliştirilmesinden sonra ortaya çıktı ve tüm bu harika tasarım modellerinin çok önemli olduğu yerde geliştiler. Ancak, basit bir web tabanlı maaş bordrosu veya basit bir iş uygulaması yapıyorsanız, yalnızca 100'lerce kullanıcıya dağıtılacağı bir milyon kullanıcı için oluşturmak için zaman harcamak yerine, gelişiminizde zamanla gelişmeniz daha iyidir.
Filtrelenmiş Görünüm Olarak Depo - ISecureRepository
Diğer taraftan, havuz, mevcut kullanıcıya / role göre gerekli doldurucuyu uygulayarak verilere erişimi koruyan, EF'nin filtrelenmiş bir görünümü olmalıdır.
Ancak bunu yapmak, depoyu daha da karmaşık hale getirir, çünkü bakımı büyük bir kod tabanıyla sonuçlanır. İnsanlar, farklı kullanıcı türleri veya varlık türlerinin kombinasyonu için farklı depolar oluşturur. Sadece bu değil, aynı zamanda birçok DTO'yla da karşımıza çıkıyor.
Aşağıdaki yanıt, tüm sınıflar ve yöntemler kümesi oluşturmadan Filtrelenmiş Depo'nun örnek bir uygulamasıdır. Soruya doğrudan cevap vermeyebilir ancak bir tanesini türetmede faydalı olabilir.
Sorumluluk reddi: Entity REST SDK'nın yazarıyım.
http://entityrestsdk.codeplex.com
Yukarıdakileri akılda tutarak, CRUD işlemleri için filtreleri tutan SecurityContext'e dayalı filtrelenmiş görünüm deposu oluşturan bir SDK geliştirdik. Ve sadece iki tür kural herhangi bir karmaşık işlemi basitleştirir. Birincisi varlığa erişim, diğeri ise mülkiyet için Okuma / Yazma kuralı.
Bunun avantajı, farklı kullanıcı türleri için iş mantığını veya depoları yeniden yazmamanız, onlara erişimi engellemeniz veya vermenizdir.
public class DefaultSecurityContext : BaseSecurityContext {
public static DefaultSecurityContext Instance = new DefaultSecurityContext();
public static long UserID{
get{
return long.Parse( HttpContext.Current.User.Identity.Name );
}
}
public DefaultSecurityContext(){
}
protected override void OnCreate(){
var acc = CreateRules<Account>();
acc.SetRead( y => x=> x.AccountID == UserID ) ;
acc.SetWrite( y => x=> x.AccountID == UserID );
acc.SetProperties( SecurityRules.ReadWrite,
x => x.AccountName,
x => x.EmailAddress);
acc.SetProperties<Account>( SecurityRules.Read,
x => x.AccountType);
var order = CreateRules<Order>();
order.SetRead( y => x => x.CustomerID == UserID );
order.SetWrite( y => x => x.CustomerID == UserID
&& x.OrderStatus != "Complete" );
order.SetProperties( SecurityRules.ReadWrite,
x => x.OrderNotes,
x => x.OrderStatus );
order.SetDelete(order.NotSupportedRule);
}
}
Bu LINQ Kuralları, her işlem için SaveChanges yönteminde Veritabanına göre değerlendirilir ve bu Kurallar Veritabanının önünde Güvenlik Duvarı görevi görür.