2012-06-30 27 views
11

CQRS ve etki alanı olayları kavramlarını kullanarak bir etki alanı modeline sahip bir uygulama yapıyorum (ancak olay kaynağı yok, sadece düz eski SQL). SomethingChanged tür olaylarla ilgili hiçbir sorun yoktu. Sonra SomethingCreated olayları uygulamakta takıldım.Etki alanı olayında yeni varlık kimliği

Kimlik birincil anahtarlı bir tabloyla eşlenen bazı varlıkları oluşturduğumda, varlık kalıcı olana kadar Kimliği bilmiyorum. Varlık kalıcılıktan uzaktır, dolayısıyla bir varlığı kuruluş içinden yayınlarken, Kimliği bilinmez - yalnızca context.SaveChanges() öğesini çağırdıktan sonra büyülü olarak ayarlanır. Peki, Olay verilerini nasıl/nerede/ne zaman kullanabilirim? olay öğeye gönderim dahil

  • :

    ben düşünüyordum. Bu, etki alanı içinde çalışır, ancak, olaylar/iletilerle iletişim kuran çoklu özerk sisteme sahip, dağıtılmış bir ortamda çok fazla olmamalıdır.

  • Yayınlama için kaydedilen olayları bir şekilde güncellemek için SaveChanges() öğesini geçersiz kılın. Ancak olayların değişmez olması gerekiyor, bu yüzden çok kirli görünüyor.
  • Kimlik yapısından kurtulma ve varlık yapıcısında oluşturulan GUID'leri kullanma. Bu en kolay olabilir ancak performansa çarpabilir ve hata ayıklama veya sorgulama gibi başka şeyleri daha da zorlaştırabilir (where id = 'B85E62C3-DC56-40C0-852A-49F759AC68FB', MIN, MAX vb.). Birçok örnek uygulamada gördüğüm bu.
  • Karma yaklaşım - kimliğini yalnız bırakın ve daha çok yabancı anahtarlar ve daha hızlı bağlantılar için kullanın, ancak GUID'yi, uygulamadaki depodan varlıkları aldığım benzersiz tanımlayıcı olarak kullanın.
+3

Etkinliğin varlığına bir başvuru eklemeyin. Kaydettikten sonra kimliğin üstesinden gelmek güzel. Yayınlamada değişmez olarak düşünülmelidir. Ancak, bu, olay üretme bağlamında yeniden denemeler yapmaya izin verirseniz sorun yaratabilir.Kimliklerin dışarıdan atanmasında bir değer var, bu yüzden bunun varsayılan bir strateji olması gerektiğini düşünüyorum. Yani hem GUID'leri hem de hibrit yaklaşımı kullanarak işe yarayabilir. Başka bir yaklaşım, bazı HILO mekanizması veya kar tanesi gibi bir şey olabilir. –

+0

HILO ve kar tanesi üzerinde ayrıntılı bilgi verir misiniz? – Pein

+0

http://nhforge.org/blogs/nhibernate/archive/2009/03/20/nhibernate-poid-generators-revealed.aspx ve http://engineering.twitter.com/2010/06/announcing-snowflake.html –

cevap

9

Sayısal kimlikleri sorunlara yol açan özellikle çok kullanıcılı, dağıtılmış ortamlarda, benzersiz tanımlayıcılar için GUID'leri kişisel olarak severim. Bu nedenle, asla veritabanı oluşturulmuş kimlik sütunları/özellikleri kullanmıyorum ve bu sorun gider.

Bunun bir nedeni, CQRS'yi izlediğiniz için, şüphesiz, yeni örneği oluşturmak ve depoyu (context.SaveChanges aracılığıyla) kullanarak yeni nesneyi devam ettirmek için gerekli adımları gerçekleştiren bir CreateSomethingCommand ve buna karşılık gelen CreateSomethingCommandHandler'ınız vardır. Etki alanı nesnesinin kendisinden ziyade SomethingCreated olayını burada yükseltirim.

Birincisi, bu, sorun giderir çünkü komut işleyicisi, veritabanı işleminin tamamlanmasını, kimlik değerini dışarı çekmesini, nesneyi güncelleştirmesini ve ardından olaydaki kimliği iletmesini bekleyebilir. Ancak, daha da önemlisi, aynı zamanda 'yaratılan' nesnenin tam olarak ne zaman olduğu sorusunu da ele alıyor?

Yapıcıların yalın olması ve yalnızca başlatma işlemini gerçekleştirmesi gerektiğinden, kurucudaki bir etki alanı olayının yükseltilmesi kötü bir uygulamadır. Ayrıca, modelinizde, nesne atanmış bir kimliği bulunana kadar gerçekten oluşturulmaz. Bu, kurucu tarafından çalıştırıldıktan sonra gereken ek başlatma adımları olduğu anlamına gelir. Birden fazla adımınız varsa, yürütme sırasını (başka bir anti-desen) zorlar mı, yoksa her ne zaman tamamlandığını (ooh, koklamak) anlamak için her birine bir kontrol yaptırır mısın? Umarım bunun hızlı bir şekilde elden nasıl sarılacağını görebilirsiniz.

Benim önerim, olayı komut işleyicisinden yükseltmektir. (Not: GUID tanımlayıcılarına geçiş yapsanız bile, bu yaklaşımı izlerim çünkü hiçbir zaman yapıcılardan olayları yükseltmemelisiniz.)

+5

"Benim önerim, olayın komut işleyicisinden kaldırılmasıdır" => Olaylar, etki alanı modelinin bir parçası olmalıdır. Fakir bir kurucunun yerine, anlamını arttırmak için, statik bir fabrika yaratacağım: 'yaratmak', başarı durumunda olayı yükseltmek. – Mik378

+0

"Birincisi, bu sorununuzu çözüyor çünkü komut işleyici, veritabanı işleminin tamamlanmasını, kimlik değerini çekmesini bekleyebilir" - zaman aşımı bir şekilde ortaya çıkıyorsa: nesne oluşturulur, ancak komut işleyicisi bir istisna atar mı? Basitlik uğruna, komut işleyicisini UoW olarak uygulamak istiyorum. Böyle bir durumda, kimlik kimliğini alan kimliği yerine kimlik kimliği alanı olarak kullanmak zorundasınız. –