2010-01-06 11 views
22

Próbujemy uzyskać CQRS. Mamy sytuację sprawdzania poprawności, w której CustomerService (usługa domeny) musi wiedzieć, czy istnieje Klient. Klienci są unikalni pod swoim adresem e-mail. Nasze repozytorium klienta (ogólne repozytorium) ma tylko Get (identyfikator) i Add (klient). W jaki sposób CustomerService powinien ustalić, czy Klient istnieje?Zapytania dotyczące domen w CQRS

Odpowiedz

23

Zobacz blog: Set based validation in the CQRS Architecture.

Zajmuje się tym problemem. Jest to złożony problem, z którym trzeba sobie poradzić w CQRS. To, co sugeruje Bjarte, polega na przeszukiwaniu bazy danych raportowania pod kątem istniejących adresów e-mail klientów i wydaniu polecenia kompensacyjnego (takiego jak CustomerEmailAddressIsNotUniqueCompensatingCommand) z powrotem do Modelu domeny, jeśli został znaleziony adres e-mail. Następnie możesz wystrzelić odpowiednie zdarzenia, które mogą obejmować UndoCustomerCreationEvent.

Przeczytaj komentarze w powyższym wpisie na blogu, aby uzyskać alternatywne pomysły.

Adam D. sugeruje w komentarzu, że walidacja jest sprawą domeny. W rezultacie możesz przechowywać ReservedEmailAddresses w usłudze, która ułatwia tworzenie klientów i jest uwodniona przez zdarzenia w twoim magazynie zdarzeń.

Nie jestem pewien, czy istnieje proste rozwiązanie tego problemu, który wydaje się być całkowicie czysty. Daj mi znać, co wymyślisz!

Powodzenia!

+17

Jak wspomniano w drugiej odpowiedzi, nie należy wykonywać kwerendy przeciwko model widoku jako część poleceń przetwarzania. Jeśli cokolwiek, te kwerendy powinny być wykonywane przez klienta przed wysłaniem polecenia, nie wysyłając polecenia na podstawie wyników. –

+10

@Udi Dahan Naprawdę nie wiem jak to działa z perspektywy SOA z tym przykładem nazwy użytkownika. Kiedy otrzymam CreateNewUserCommand, z pewnością muszę sprawdzić, czy nazwa użytkownika jeszcze nie istnieje? Nie mogę założyć, że klient wykonał już tę kontrolę, szczególnie jeśli klientem może być aplikacja innej firmy? Rozumiem powody niewykonania kwerend podczas przetwarzania komend, ale mogę wymyślić kilka scenariuszy, w których podczas przetwarzania polecenia potrzebuję analizować dane znajdujące się poza agregatem, w którym polecenie ma działać na ... –

+11

Aplikacje innych firm łączyłyby się z dobrze zachowanym "klientem", który mógłby być usługą sieciową, i to on dokonuje kontroli w stosunku do modelu widoku, a jeśli kontrole przejdą, wysyła wiadomość w jedną stronę do "serwera". ". –

5

Te kwestie nie musi być aż tak skomplikowane:

  1. Sprawdź swój sklep raportowania dla wyjątkowość klienta przed złożeniem polecenia UpdateCustomer.
  2. Dodaj wiązanie do bazy danych dla unikalności na adres e-mail. Podczas wykonywania polecenia obsłuż wyjątek i wyślij powiadomienie do użytkownika za pomocą kanału odpowiedzi. (Hences nigdy zapłonów CustomerUpdated do sklepu sprawozdawczego.

Korzystając z bazy danych do tego co jest dobre dla i nie daj się powiesił na ograniczenia ORM.

+8

Co jeśli to nie jest baza danych? – andho

+2

Co powiesz na polecenia współbieżne? Dwóch klientów można utworzyć w niektórych (rzadkich, ale możliwych) okolicznościach. –

5

Ten post przez Udi Dahan http://www.udidahan.com/2009/12/09/clarified-cqrs/ zawiera następujące pkt :

„Ponadto, nie powinniśmy mieć dostęp do sklepu zapytań do przetworzenia polecenia - każdy stan, który jest potrzebny powinny być zarządzane przez autonomiczny składnik - to część rozumieniu autonomii.”

Wierzę, że Udi zasugerował po prostu dodanie unikalnego ograniczenia do bazy danych.

Ale jeśli nie masz ochoty tego robić, na podstawie powyższego wyciągu, sugerowałbym dodanie do repozytorium metody "ByEmail" i na tym koniec - ale z drugiej strony Udi prawdopodobnie miałby lepszą propozycję ..

+3

Nie działa to jednak we wszystkich scenariuszach, na przykład używam bazy danych NoSQL, która nie obsługuje pojęcia "ograniczenia". – James

+0

@james Jaka jest baza danych nosql? –

2

Mam nadzieję, że nie jest za późno ... ale stanęliśmy w podobnej sytuacji w naszym projekcie, faktycznie przechwytywamy executor poleceń i dołączamy go do zestawu reguł utworzonych dla tego polecenia, który z kolei używa zapytania aby pobrać dane.

W tym przypadku możemy mieć klasę o nazwie CustomerEmailMustBeUniqueRule, która jest pobierana przez RuleEngine, gdy polecenie "RegisterCustomerCommand" ma zostać wykonane przez RegisterCustomerCommandExecutor.Klasa ta reguła ma obowiązek zapytanie do bazy danych, aby dowiedzieć się, czy istnieje id e-mail i zatrzymać wykonywanie przez podniesienie nieprawidłową flagę ...

0
  1. użyjemy ORM do tabeli Customer. W ten sposób wygenerowałby wyjątek po wprowadzeniu duplikatu klucza. Powinieneś używać DapperDotNet, jest on bardzo lekki i łatwy w użyciu. Zaletą korzystania z ORM jest to, że większość z nich pozwala na generowanie lub tworzenie klas reprezentujących istniejące tabele w bazie danych. Całkowicie wycina część, w której musisz sprawdzić względem bazy danych dla istniejącego rekordu.

  2. Można również wprowadzić polecenie, zaimplementować interfejs, który wykonuje sprawdzanie za pomocą menedżera danych, jednak nie jest to konieczne.

W większości przypadków, co chcesz wyjątek jeśli duplikat klucz jest wpisany. Dałoby to również swobodę, aby nie musieć tworzyć zapytań, aby sprawdzić istnienie.

Powiązane problemy