Varlık Çerçevesi ile Etki Alanında Tasarımın Tuzakları


12

İncelediğim DDD hakkında birçok ders çoğunlukla teoriyi kapsıyor. Hepsinin ilkel kod örnekleri vardır (Çoğul görüş ve benzeri).

Web'de ayrıca birkaç kişi tarafından DDD ile EF'yi kapsayan öğreticiler oluşturma girişimleri de vardır. Onları kısaca incelemeye başlarsanız - birbirlerinden çok farklı olduklarını hemen fark edersiniz. Bazı insanlar uygulamayı asgari düzeyde tutmayı ve EF'nin üstüne depo gibi ek katmanlar eklemekten kaçınmayı önerir , diğerleri kesinlikle ekstra katmanlar oluşturur, hatta genellikle Agrogate Roots'a enjekte ederek SRP'yi ihlal eder DbContext.

Fikir temelli bir soru sorarsam çok özür dilerim ama ...

Uygulama söz konusu olduğunda - Entity Framework en güçlü ve en yaygın kullanılan ORM'lerden biridir. Ne yazık ki DDD'yi kapsayan kapsamlı bir kurs bulamayacaksınız.


Önemli hususlar:

  • Entity Framework, UoW & Repository ( DbSet) öğesini kutudan çıkarır

  • EF ile modellerinizde gezinme özellikleri bulunur

  • EF ile modellerin hepsi her zaman mevcut kapalı DbContext(onlar olarak temsil edilir DbSet)

tuzaklar:

  • Eğer olamaz Modellerinizin navigasyon özelliklerine sahip ve bu onları ve aramayı değiştirmek mümkündür - Çocuğunuz modeller sadece Agrega Root yoluyla etkilenir garantidbContext.SaveChanges()

  • ile DbContextsize böylece her türlü modeli erişebilir engellemeyi Agrega Root

  • Eğer aracılığıyla kök nesnenin çocuklara erişimi kısıtlayabilir ModelBuilderiçinde OnModelCreatingyöntemle alanlar olarak işaretleyerek (Hala DDD hakkında en doğru yol olduğuna inanmıyorum artı bunun gelecekte yol açabilir maceralar tür neyi değerlendirmek zor - oldukça şüpheci )

Çatışmalar:

  • Agrega döndüren başka bir depo katmanı uygulamadan , yukarıda belirtilen tuzakları kısmen çözemeyiz

  • fazladan bir depo katmanı uygulayarak EF'in yerleşik özelliklerini görmezden geliyoruz (her DbSetbiri zaten bir repo) ve uygulamayı aşırı derecede karmaşıklaştırıyoruz


Kanımca:

Lütfen cehaletimi affedin, ancak yukarıdaki bilgilere dayanarak - Varlık Çerçevesi Etki Alanına Dayalı Tasarım için yeterli değildir veya Etki Alanına Dayalı Tasarım kusurlu ve eski bir yaklaşımdır.

Her yaklaşımın avantajları olduğundan şüpheleniyorum, ancak şimdi tamamen kayboldum ve EF'yi DDD ile nasıl uzlaştıracağına dair en ufak bir fikrim yok.


Eğer yanılıyorsam - EFD ile DDD'ye nasıl gidilebileceğine dair herkes en azından basit bir talimat setini detaylandırabilir (hatta iyi kod örnekleri sağlayabilir), lütfen?


EF'in nasıl çalıştığını anladığım kadarıyla buradaki adımları detaylandırdım . Yine de bu adımlar, çocuklara nav yoluyla erişme sorununu ele almamaktadır. özellikleri veya DbSets tarafından DbContext kapalı.
Alex Herman

Yanıtlar:


8

DDD ve EF'nin birbirleriyle hiçbir ilgisi yoktur.

DDD bir modelleme konseptidir. Etki Alanı, İş Gereksinimleri hakkında düşünmek ve bunları modellemek anlamına gelir. Özellikle nesne yönelimi bağlamında, iş işlevlerini ve yeteneklerini yansıtan bir tasarım yaratmak anlamına gelir.

EF bir kalıcılık teknolojisidir. Esas olarak veri ve veritabanı kayıtları ile ilgilidir.

Bu ikisi keskin bir şekilde boşandı. Bir DDD tasarımı EF'yi kaputun altında bir şekilde kullanabilir, ancak ikisi başka bir şekilde etkileşime girmemelidir.

Etki Alanına Dayalı Tasarım'ın bazı yorumları aslında veri modellemeyi savunmaktadır ve bence sorunuz budur. Bu yorumda "Varlıklar" ve "Değer Nesneleri" yalnızca işlevsiz veri sahipleridir ve tasarım, bunların hangi özelliklere sahip olduğu ve aralarındaki ilişki ile ilgilidir. Bu bağlamda DDD ve EF karşılaşabilir.

Ancak bu yorum kusurludur ve bunu tamamen görmezden gelmenizi şiddetle tavsiye ederim.

Sonuç olarak : DDD ve EF birbirlerini dışlamazlar, veri modelleme değil, doğru nesne modelleme yaptığınız sürece aslında birbirleriyle alakasızdırlar. DDD nesneleri EF yapıları şeklinde veya biçiminde olmamalıdır. DDD Varlıkları gerektiği değil , örneğin EF "varlıklar" olmak. Bazı işle ilgili işlevlerde, DDD tasarımı EF ile ilgili bazı veri nesneleriyle birlikte kullanılabilir, ancak bunlar işle ilgili davranış odaklı bir arabirim altında her zaman gizlenmelidir.


1
EF sadece zaman tasarrufu sağlar. Değişiklik izleme ve agregaların sürekliliği EF'in zaten çok yardımcı olduğu yerdir. Ne yazık ki, şu anda konfigürasyon düzeyinde agregaların şeklini tanımlamanın bir yolu yoktur.
Pavel Voronin

6

EF'e, ham ADO.NET'ten yalnızca biraz daha güçlü yazılan veri erişim kütüphanesi gibi davranın. Etki alanınızı, ham DataSet veya DataTable kullanarak etki alanı modellemenizi önermediğim gibi EF varlık sınıflarını kullanarak modellemenizi önermem.

EF'nin veritabanı erişimi ve etki alanı modellemesi arasında bir kısayol olarak satıldığını anlıyorum, ancak bu yaklaşım büyük ölçüde ilgisiz iki sorunu ele aldığı için özünde kusurlu. .NET'te bir sınıfın tamamen ilgisiz bazı şeyler (ör. .NET Remoting) gerçekleştirmesini sağlamak için başka girişimler de vardı ve bunlar iyi bitmedi.

DDD'yi POCO sınıflarını kullanarak yapın ve veritabanı şemasının tasarımınızı yönlendirmesine izin vermeyin. EF'yi depo / kalıcılık katmanının içinde tutun ve EF varlıklarının dışarıya sızmasına izin vermeyin.


5

Entity Framework, UoW & Repository'yi (DbSet) kutudan çıkarır

Hayır.

Entity Framework soyutlamaları DDD ile değil ORM ile oluşturuldu. DbSetİdare Framework herhangi bir sürümünde soyutlama bir DDD Deposu basitliğinden hiçbir yerde yakın - değil söz etmek DbContextbir UnitOfWork daha milyonlarca şeyler ortaya çıkarır.

DbSet<TEntity>DDD'de ihtiyaç duymadığımız EF Core 2.1'in özetindeki öğelerin kapsamlı olmayan bir listesi :

  • Attach(TEntity) ve tüm kardeşleri
  • Find(Object[])
  • Update(TEntity) ve tüm kardeşleri
  • Uygulama IQueryable

Onlarla gereksiz bağımlılıklar boyunca sürüklemeye ek olarak, bunlar normalde çok basit toplama davranışını ortaya koyan bir Deponun amacını gizler. Ayrıca sızdıran soyutlamalar, geliştiricilerin kendilerini EF ile çok fazla eşleştirmeleri ve Endişelerin Ayrılması tehdidiyle sürekli bir ayartmadır.

Alt satır: Bu yağları güzel, aerodinamik kavramlara sarmalı ve ne olduğunu tahmin etmelisiniz, bu da ekstra sınıflar getirmek anlamına geliyor.

EF ve DDD ile neler yapabileceğinize ilişkin nispeten sağlam bir örnek (ifade edilen bazı bakış açıları tartışmalı olsa da): https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/

diğerleri kesinlikle ekstra katmanlar üretiyor, hatta çoğu kez DbContext'i Toplu Köklere enjekte ederek SRP'yi bile ihlal ediyor

Bu cümlenin iki kısmı arasındaki bağlantıyı gerçekten görmüyorum. Yaklaşım ne olursa olsun, DDD'de Uygulama Hizmeti adı verilen bir şey vardır ve iş / Depo (veya DbContext) Birimini manipüle ettiğiniz yer burasıdır . Agrega Köklerinde değil.

Eğer eğitimli bir takas olsaydı geçerli bir yaklaşım olsa da, son Depo, "Varlık Çerçevesi minimalizmi" eğilimi sanrısaldır. Çerçevesini kutusundan çıkar çıkmaz en iyi uygulamalarla uyumlu hale getirmek için hiçbir şey yapmayan EF yaratıcıları olduğunda, Entity Framework ile gerçekleşen sürtünme için DDD kalıplarını suçlar. Tüm bunlar, kod güvenliği ve oluşabilecek sürdürülebilirlik açısından tüm sorunlarla sıkı bir şekilde bu çerçeveye bağlanıyor.


2

Çatışmalar:

Agrega döndüren başka bir depo katmanı uygulamadan, yukarıda belirtilen tuzakları kısmen çözemiyoruz bile

ekstra bir depo katmanı uygulayarak EF'in yerleşik özelliklerini görmezden geliyoruz (her DbSet zaten bir repo) ve uygulamayı aşırı derecede karmaşıklaştırıyoruz

Her Aggregate'in kendi DBContext'ini aldığı ve Aggregate için gerekenleri eşleştirdiği bir yaklaşım kullandım. Sanırım bu Julie Lerman tarafından da tanımlandı.

Bu çok işe yaradı, ancak konseptlerinizi varlıklarınızla ilişkilendirmek istemediğiniz daha ilginç modeller için yeterli olmayabilir.



Toplam Başına DBContext yaklaşımının herhangi bir faydası var mı? EF ile DDD'yi uygulamanın varsayılan yolu bu mu?
Alex Herman

Julie Lerman, Sınırlı bağlam başına DbContext anlamına gelmedi mi?
Mvision

0

Sadece olası çözüm önerilerini paylaşmak isteriz:

  1. Servis projesinde doğrudan EF projesine başvurmaktan kaçının

  2. fazladan bir Depo Katmanı oluşturun (EF projesini kullanır ve Toplam Kökü döndürür)

  3. Hizmet Katmanı'ndaki Havuz Katmanı projesine başvurma

Mimarlık :

  • UI

  • Denetleyici Katmanı

  • Hizmet Katmanı

  • Havuz Katmanı

  • Varlık Çerçevesi

  • Çekirdek Proje (EF modellerini içerir)


Bu yaklaşımla gördüğüm tuzaklar:

  • Havuz EF model ağacı olarak değil, Toplam Kök döndürürse (örn. eşlenmiş bir nesne döndürürsek) - EF'in değişiklikleri izleme yeteneğini kaybediyoruz

  • Agrega Kökü bir EF modeliyse - ilgilenemesek bile tüm navigasyon özellikleri hala kullanılabilirDbContext (Servis Katmanı'nda EF projesine referans vermiyoruz)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.