Do you use aggregate root (AR) types for event parameters?
For example, the first method works with simple types but the second uses complex types. Why do you prefer the first or the second?
AggregateRoot()
{
private SomeAR _someAR;
public void DoSomething(SomeAR so开发者_如何学GomeAR)
{
// Validation and other similar stuff.
ApplyEvent(new SomethingHappenedEvent(someAR.StringText));
}
public void DoAnything(SomeAR someAR )
{
ApplyEvent(new NothingHappenedEvent(this, someAR));
}
protected void OnDoSomething(SomethingHappenedEvent e)
{
_someAR = ???
}
}
Do question why you are passing in that entity and/or aggregate. What is it that you are really after from those objects? I'll tell you, it's their state or a side-effect free function that produces state you want to put in that event.
Coupling your events to your aggregates/entities is going to be hard on your consumers, especially if messaging is involved. Pretty soon you'll be sprinkling serialization attributes on your aggregate's/entity's state (be it fields or properties). Maybe you'll start to introduce state to be able to give the event the data it wants upon serialization. Bad idea, because you're giving your aggregates/entities a responsibility - keeping track of state for purposes other than its own behavior - they shouldn't have in the first place.
It's not only the coupling and messaging, it's also a matter of choice: the freedom to represents things differently on the inside (aggregates/entities) and on the outside (events/commands). Most domain objects on the inside are all about behavior, while on the outside the event/command objects are about carrying state and intent forward.
All that said, there's nothing wrong with double-dispatching into an object to get to it's state.
I'd keep it simple and only pass the minimal amount of data within the event. Just enough for the event handler to make appropriate state changes to your aggregate root. This will help when serializing your events for messaging and storing to an event store.
As far as my understanding goes, events can only have basic data types or at most value objects. We cannot have an aggregate root (AR) in the event. The second recommendation would be not to use an AR in another AR. If say I have AR A and Entity B, I will write it like this:
public class A : AggregatRoot
{
B b;
public A()
{
b = new B();
}
public void ChangeBsAttributes(int c)
{
b.ChangeMyAttributes(c);
}
}
public class B : EntityMappedByConvention
{
int _c;
B()
{
}
public void ChangeMyAttributes(int c)
{
ApplyEvent(MyAttributesChanged(c);
}
public void OnMyAttributesChanged(MyAttributesChanged evnt)
{
_c = evnt.C;
}
}
精彩评论