Business Object Events

28 views
Skip to first unread message

Polemann

unread,
Jul 14, 2010, 8:32:52 AM7/14/10
to ncqrs-dev
Okay,
I've done commands now but now I need to understand the thinking
behind the events (and the event publishing). I want to use the
command model without a centralised store of events (dont ask why :))
and store the data, the old way, in the data base in a referential
db.

When someone does that the event handler on the objects don't seem to
make as much sense as I see the primary purpose for the event handlers
on an object to re-buld the object back to its current state. My
domain still need to publish these events but its just that I don't
think the domain object necessarily needs to listen out for the
changes.

Has anyone else only implemented part of the ncqrs metholodogy ?



So the domain object would become simpler....

namespace Domain
{
public class Note : MyNotesAggregateRoot
{
private String _text;

private Note()
{
// Need a default ctor for Ncqrs.
}

public Note(String text)
{
var clock = NcqrsEnvironment.Get<IClock>();

ApplyEvent(new NewNoteAdded{NoteId = Id,Text =
text,CreationDate = clock.UtcNow()});
}

public void ChangeText(String newText)
{
ApplyEvent(new NoteTextChanged{NoteId = Id, NewText =
newText });
}

protected void OnNewNoteAdded(NewNoteAdded e)
{Id = e.NoteId; _text = e.Text;}

protected void OnNoteTextChanged(NoteTextChanged e)
{
_text = e.NewText;
}
}
}


----would become--------------

namespace Domain
{
public class Note : EventSource
{
private String _text;

private Note()
{
// Need a default ctor for Ncqrs.
}

public Note(String text)
{
var clock = NcqrsEnvironment.Get<IClock>();
_text = text;
RaiseEvent(new NewNoteAdded { NoteId = Id, Text = text,
CreationDate = clock.UtcNow() });
}

public void ChangeText(String newText)
{
_text = newText;
RaiseEvent(new NoteTextChanged { NoteId = Id, NewText =
newText });
}
}
}


Pieter Joost van de Sande

unread,
Jul 14, 2010, 12:48:22 PM7/14/10
to ncqr...@googlegroups.com
Hey Scott,

Okay,
I've done commands now but now I need to understand the thinking
behind the events (and the event publishing).  I want to use the
command model without a centralised store of events (dont ask why :))
and store the data, the old way, in the data base in a referential
db.

Why? :)

Really, that is an important question. I don't see any reason why you do not want to keep the events. The events are a unique selling point for having a cqrs architecture and they give you all of great advantages.
 
When someone does that the event handler on the objects don't seem to
make as much sense as I see the primary purpose for the event handlers
on an object to re-buld the object back to its current state. My
domain still need to publish these events but its just that I don't
think the domain object necessarily needs to listen out for the
changes.

I think you still want the event handler to update the internal state of the object via raising an event. This to make sure all the state transitions are covered by the events.

Chris Chilvers

unread,
Jul 14, 2010, 2:26:55 PM7/14/10
to ncqrs-dev
Well I was looking at a similar thing to start migrating an existing
app to CQRS. I don't think NCQRS will be worthwhile without the event
sourcing since that is the main feature it adds. Without the event
sourcing you just have a message based system + ORM, which could be
handled with something like Rhino ESB and NHibernate.

There might be some value in the command & event mapping, though
IRepository and the standard domain events and domain object base
classes are not the useful without an event stream, since that is
their main function, coordinating the event stream.

For our project the commands and user tasks are reasonably well
defined so I'm just separating the query part out, then I can look at
simplifying the domain model without the UI being a concern. At which
point I can then create the actual commands and finally add in NCQRS
to get event sourcing. Then just have to work out what to do with
existing data, some sort of legacy Import event I guess.

On Jul 14, 5:48 pm, Pieter Joost van de Sande <p...@born2code.net>
wrote:

Scott Reynolds

unread,
Jul 14, 2010, 4:58:11 PM7/14/10
to ncqr...@googlegroups.com

Chris... did you ever think of the domain model only publishing events and then the repository being loosely coupled by the events.

Do we perhaps need the ability to define event handlers to be sync or asynchronous

On 14 Jul 2010 19:27, "Chris Chilvers" <chil...@googlemail.com> wrote:

Well I was looking at a similar thing to start migrating an existing
app to CQRS. I don't think NCQRS will be worthwhile without the event
sourcing since that is the main feature it adds. Without the event
sourcing you just have a message based system + ORM, which could be
handled with something like Rhino ESB and NHibernate.

There might be some value in the command & event mapping, though
IRepository and the standard domain events and domain object base
classes are not the useful without an event stream, since that is
their main function, coordinating the event stream.

For our project the commands and user tasks are reasonably well
defined so I'm just separating the query part out, then I can look at
simplifying the domain model without the UI being a concern. At which
point I can then create the actual commands and finally add in NCQRS
to get event sourcing. Then just have to work out what to do with
existing data, some sort of legacy Import event I guess.

On Jul 14, 5:48 pm, Pieter Joost van de Sande <p...@born2code.net>
wrote:

> Hey Scott,
>
> Okay,
>
> > I've done commands now but now I need to understand the thinking

> > be...

Pieter Joost van de Sande

unread,
Jul 14, 2010, 5:00:37 PM7/14/10
to ncqr...@googlegroups.com
Scott, I'm still wondering what the reason is you don't want to store the events that get published?

Scott Reynolds

unread,
Jul 14, 2010, 5:11:59 PM7/14/10
to ncqr...@googlegroups.com

It's not that I do not want them its that the place I work isn't convinced. We may store the events as an audit but reconstruction of an object will most likely be from the standard relational FB. I am trying hard to convince people.

On 14 Jul 2010 22:01, "Pieter Joost van de Sande" <p...@born2code.net> wrote:

Scott, I'm still wondering what the reason is you don't want to store the events that get published?



On Wed, Jul 14, 2010 at 10:58 PM, Scott Reynolds <sc...@reynoldsphotography.com> wrote:
>

> Chris....

Scott Reynolds

unread,
Jul 14, 2010, 5:17:16 PM7/14/10
to ncqr...@googlegroups.com

And does and aggregate root need to know so much about the repository....... can we just not publish events to the database from the raise event methods......

I also don't understand why an aggregate root has a list of events.....

The only other thing I don't fully understand today is why you a momento is used to get a snapshot as the domain object seems to have many responsibilities........

On 14 Jul 2010 22:01, "Pieter Joost van de Sande" <p...@born2code.net> wrote:

Scott, I'm still wondering what the reason is you don't want to store the events that get published?



On Wed, Jul 14, 2010 at 10:58 PM, Scott Reynolds <sc...@reynoldsphotography.com> wrote:
>

> Chris....

Pieter Joost van de Sande

unread,
Jul 14, 2010, 5:19:04 PM7/14/10
to ncqrs-dev
I understand Scott. Change in architecture, or introducing new concepts can be really hard to sell. Also most people can only handle X amount of change at the time and you probably already introduced new concepts. Some people need time to get used to the concepts before they are willing to go a step further. With that said, I advice you to develop your aggregate roots so that in the future you can easily add an event store to the system it from where you dehydrate aggregates from. You should leave that option open if it is possible. I can imagine a point in time where maintaining the standard relation FB including mappings will be a pain in the ass and you have a change to introduce the event store for dehydration as well.

Pieter Joost van de Sande

unread,
Jul 14, 2010, 5:25:33 PM7/14/10
to ncqrs-dev

And does and aggregate root need to know so much about the repository....... can we just not publish events to the database from the raise event methods......


The aggregate root does not know anything about the repository at the moment. 
 

I also don't understand why an aggregate root has a list of events.....

This is because a method on a agg root can raise multiple events. You don't want to publish these events before everything is valid. For example, when method Foo raises two events the FooEvent and the BarEvent. Foo is called, FooEvent is raised, but just before BarEvent will be raised you hit a business rule that breaks. You maybe want to rollback, or not commit, these events. You want to publish all the events when the state of the agg root is accepted. This is currently done by accepting the UnitOfWorkContext.

The only other thing I don't fully understand today is why you a momento is used to get a snapshot as the domain object seems to have many responsibilities........


You don't need to have mementos for all agg roots. Gregs states yesterday that only 10% of your agg roots will probably have these. Since you only need this on agg roots that live very long and have hundreds of event to dehydrate from.

I hope this clarifies some things.

Scott Reynolds

unread,
Jul 14, 2010, 5:25:50 PM7/14/10
to ncqr...@googlegroups.com

Indeed it will be a pain...... I'm hoping to prove an event stores worth hydration can be a repository only responsibility ......

Actually I may have just had a good idea...... if I can get a snapshot event published the aggregate root than I may do without momento.......

On 14 Jul 2010 22:19, "Pieter Joost van de Sande" <p...@born2code.net> wrote:

I understand Scott. Change in architecture, or introducing new concepts can be really hard to sell. Also most people can only handle X amount of change at the time and you probably already introduced new concepts. Some people need time to get used to the concepts before they are willing to go a step further. With that said, I advice you to develop your aggregate roots so that in the future you can easily add an event store to the system it from where you dehydrate aggregates from. You should leave that option open if it is possible. I can imagine a point in time where maintaining the standard relation FB including mappings will be a pain in the ass and you have a change to introduce the event store for dehydration as well.



On Wed, Jul 14, 2010 at 11:11 PM, Scott Reynolds <sc...@reynoldsphotography.com> wrote:
>

> It's n...

Scott Reynolds

unread,
Jul 14, 2010, 5:27:49 PM7/14/10
to ncqr...@googlegroups.com

Shouldn't unitofwork have the  unsaid events rather than the aggregateevents

On 14 Jul 2010 22:25, "Pieter Joost van de Sande" <p...@born2code.net> wrote:

> And does and aggregate root need to know so much about the repository....... can we just not publi...

The aggregate root does not know anything about the repository at the moment. 


 
>
> I also don't understand why an aggregate root has a list of events.....

This is because a method on a agg root can raise multiple events. You don't want to publish these events before everything is valid. For example, when method Foo raises two events the FooEvent and the BarEvent. Foo is called, FooEvent is raised, but just before BarEvent will be raised you hit a business rule that breaks. You maybe want to rollback, or not commit, these events. You want to publish all the events when the state of the agg root is accepted. This is currently done by accepting the UnitOfWorkContext.


>
> The only other thing I don't fully understand today is why you a momento is used to get a snaps...

Polemann

unread,
Jul 15, 2010, 3:39:35 PM7/15/10
to ncqrs-dev
Sorry for the last response my phone is playing up.....

Instead of implementing momento on an object (via the IMomento
interface) given that this is an event system would it make sense to
have a ISnapshotable where the domain object just raised a
XXXXSnapshotCreatedEvent (where XXXX is the object). Then we could
have a
'handler' to handle this on the object. This would have full access to
the class properties.

> I understand Scott. Change in architecture, or introducing new concepts can
> be really hard to sell. Also most people can only handle X amount of change
> at the time and you probably already introduced new concepts.

Actually I'm slowly planting the seed. As I was publishing the events
the database end of it was extremely simple. Here's hoping I can
communicate the benefits.

I don't think the EventSourcing is required at all for this framework.
I mean the database layer is really totally independent so you could
just publish the events to the repository and let them me mapped as
required (it's not ideal buy its make some sense). There's another
great advantage of events that you can 'Publish' them to an out of
process bus.

Chris Chilvers

unread,
Jul 15, 2010, 3:53:01 PM7/15/10
to ncqrs-dev

> There's another
> great advantage of events that  you can 'Publish' them to an out of
> process bus.

That is the general idea, the standard way being to deliver them to a
durable message queue such as MSMQ, RabbitMQ or Rhino Queues. The
basic in memory bus is just a very basic implementation to allow
something to work with little dependencies or complexity.
Reply all
Reply to author
Forward
0 new messages