Ich habe zwei ältere Enterprise-Anwendung, die ein paar ähnliche Funktionen haben. Ich muss ein System erstellen, das auf Datenänderungsereignisse von diesen Systemen reagiert, diese Daten verarbeitet und die kombinierten Ergebnisse über eine API in mehreren Formaten verfügbar macht. Ich würde gerne eine Event Source/DDD-Architektur verwenden, aber ich bin mir nicht sicher, ob das Sinn macht. Wie könnte ich das System nach dem untenstehenden vereinfachten Modell gestalten?Ereignisquelle, Anti-Corruption Layer-Design mit NEventStore
Hinweis - Die folgenden wurde bearbeitet, die Frage zu klären:
Beide Systeme haben Produkte, die unterschiedliche Preise basieren auf dem Datum enthalten. Wenn sich der Preis ändert, kann jedes System ein Ereignis ausgeben, PriceChanged, das die Kennung des Altsystems, den Primärschlüssel dieses Systems, ein Datum und den neuen Preis enthält. Die Produkt-ID ist einzigartig für das System, aber möglicherweise nicht eindeutig zwischen beiden Systemen, sodass auch eine System-ID enthalten ist.
PriceUpdated {
int systemId,
int productId,
Date date,
Float amount
}
Im begrenzten Rahmen meines neuen Systems würde einen Dienst sein, der dieses Ereignis empfängt und müssen mein Aggregat von systemId, productId und Datum suchen und dann einen Befehl aussenden den entsprechenden Preis in der aktualisieren Aggregat. Mein Aggregat würde definiert werden als:
class ProductPriceAggregate
{
Guid Id,
int systemId,
int productId,
Date date,
Float amount
Apply(CreateProductPriceCommand e){
Id = e.Id;
systemId = e.systemId;
productId = e.productId;
date = e.date;
RaiseEvent(new ProductPriceCreatedEvent(this))
}
Apply(UpdateProductPriceCommand d){
amount = e.amount;
RaiseEvent(new ProductPriceUpdatedEvent(this));
}
}
Wenn ich NEventStore verwende die Ströme mit einer GUID speichert, dann wird jeder aggreateId durch eine GUID dargestellt werden. Mein Dienst müsste nach der GUID fragen, indem er systemId, productId und date verwendet, um einen Befehl mit der richtigen ID auszugeben.
Der Service könnte wie folgt aussehen:
class PriceUpdateService : ISubscribeTo<PriceUpdated>{
Handle<PriceUpdated>(PriceUpdated e)
{
var aggregateId = RetrieveId(e.systemId, e.productId, e.date);
if (aggregateId == null)
Raise(new CreateProductPriceCommand(e))
else
Raise(new UpdateProductPriceCommand(aggregateId, e.amount);
}
RetrieveId(int systemId, int productId, DateTime date)
{
// ???
}
}
Die Frage ist, was der beste Weg, um die Summe der ID zu sehen ist? Die Legacy-Systeme, die das PriceUpdated-Ereignis ausgeben, haben keine Kenntnis von diesem neuen System. Kann ich ein Lesemodell verwenden, das als Antwort auf ProductPriceCreatedEvent aktualisiert wird und genügend Informationen zum Abfragen der ID enthält? Benötige ich ein anderes Aggregat, das ProductPrices indexieren soll? Wie von VoiceOfUnreason als Antwort gepostet, könnte ich eine wiederholbare Konvention verwenden, um die ID mit systemId, productId und date zu generieren. Ist dies die empfohlene Option aus DDD-Sicht?
"Würde ich dann haben" - meinst du ich hätte * stattdessen *?Denn es gibt einen klaren Unterschied zwischen dem sofortigen Auslösen eines Ereignisses und dem Ausgeben eines Befehls. Der Wortlaut macht es unklar, ob Sie sich dessen bewusst sind. – guillaume31
Mögliches Duplikat von [Event Sourcing Befehl oder Ereignis von externem System?] (Http://stackoverflow.com/questions/11888028/event-sourcing-command-or-event-from-external-system) – guillaume31
Danke für den Kommentar guillaume31 Ich habe den Beitrag aktualisiert, um meine Frage zu klären. Mein Hauptanliegen ist, wie die Aggregat-ID abgerufen wird, damit mein Dienst, der die Ereignisse von den externen Systemen behandelt, wiederum Befehle an das richtige Aggregat ausgeben kann. – Jeremy