Hi Max I am trying to learn to implement eventhorizen is there possibility to give me little example of implementation. existing sample bit complected for as i am still learning this ddd concept.
thanks so much cheers Bimal On Sunday, 23 November 2014 at 01:27:48 UTC+11 Max Ekman wrote: > Thanks for the reply! > > Good that you like the new version, I implemented it partly to show and > test the flexibility of the toolkit. I don't want to debate design > patterns, but I think it's perfectly ok to define it as delegation. From > the Wikipedia article on the pattern: > > "a helper object, known as a *delegate*, is given the responsibility to > execute a task for the *delegator*." > > http://en.wikipedia.org/wiki/Delegation_pattern > > Anyway, regarding the command handler and event bus, I did have them as > separate objects before but decided to merge them for now to simplify. I > think I will split them apart soon though, I like the other approach better. > > Regarding the EventStream I agree with you that []Event could be a bit > more idiomatic, I may change that! > > I'm also thinking of changing the returned events to be a parameter > instead of a return, much like the wonderful http.Handler interface. Lots > of inspiration to get from that. I have started using the library in a > fairly large project and I will probably change and add a lot when I get > real (and different) use cases. > > Cheers, > Max > > > > -- > > Max Persson > Software Engineer > > +46 708 710504 > m...@looplab.se > > > looplab.se > > On 22 nov 2014, at 14:43, egon <egon...@gmail.com> wrote: > > > > On Friday, 21 November 2014 15:45:55 UTC+2, Max Persson wrote: >> >> Hi Egon, >> >> I have now implemented a new dispatcher and aggregate that uses delegation >> > > It's it's forwarding, not delegation... > http://en.wikipedia.org/wiki/Delegation_(programming) > > I do like it more than the reflection based version... I also have > experimented with having CommandDispatcher and EventBus separate... that > would get rid of > > disp.AddHandler, disp.Dispatch -> disp.Register, disp.Handle > disp.AddSubscriber, disp.Dispatch -> bus.Listen, bus.Publish > > This also means, I am able to minimize the dependencies as well. If > something needs only the bus, I'll only use the bus... > > Also if you add the type as the last parameter in AddSubscriber / > AddHandler then you can use varargs... e.g. > > disp.Listen(guestListProjector, InviteCreated{}, InviteAccepted{}, > InviteDeclined{}) > > I like the returning of EventStream in CommandHandling, but maybe there is > a better way of doing it. The reason I haven't used that approach is > because if you emit multiple events and one of the later events depends on > the effects of some previous event inside the aggregate then the returning > approach will be more confusing. > > Also I would probably simply use []Event instead of EventStream. > > PS: I also implemented the guestlist example: > https://github.com/egonelbre/event/tree/master/example/guestlist > > Not a verbatim translation, but demonstrates how I would currently > implement it. (I'm still not happy with the Aggregate approach...) > > + Egon > > to let domain aggregates handle type assertion of commands and events >> themselves instead of the slightly "magical" reflection version that I >> first implemented. It would be interesting to get your thoughts on the >> implementation! >> >> See the example here: >> https://github.com/looplab/eventhorizon/tree/master/examples/delegation >> >> Cheers, >> Max >> >> On Tuesday, November 18, 2014 11:32:32 AM UTC+1, egon wrote: >>> >>> In the example create a package called "invite" then you can name the >>> events/lists as >>> >>> invite.Info >>> invite.Projector >>> >>> invite.Created >>> invite.Accepted >>> invite.Declined >>> >>> Regarding the different packages... I think you went too far with the >>> flattening :) >>> As a general tip, if you have 3 or more parts for your interface/struct >>> name then you should structure them better. >>> >>> I didn't yet intend to upload my approach, but... >>> https://github.com/egonelbre/event >>> I'm not convinced that the aggregate approach as in most CQRS examples >>> is good enough for Go. >>> >>> With my approach when implementing some aggregate you would do it: >>> >>> package thing >>> >>> type Aggregate struct { >>> event.Aggregate >>> } >>> >>> func (thing *Aggregate) Apply(e event.Event) { >>> thing.Record(e) >>> >>> switch e := e.(type) { >>> case Created: ... >>> >>> // and methods >>> func (thing *Aggregate) Append(value string){ >>> thing.Apply(Appended{value}) >>> } >>> >>> The repository would look like: >>> >>> package thing >>> >>> type Repository struct { >>> event.Store >>> } >>> >>> func (repo *Repository) Create() *Aggregate { >>> ep := &Aggregate{} >>> ep.Id = event.GenerateId() >>> return ep >>> } >>> >>> func (repo *Repository) ById(id event.AggregateId) (thing *Aggregate, ok >>> bool) { >>> events, ok := repo.Store.List(id) >>> if !ok { >>> return nil, false >>> } >>> ep = &Aggregate{} >>> ep.Id = id >>> for _, event := range events { >>> ep.Version = event.Version >>> ep.Apply(event.Data) >>> } >>> ep.Changes = nil >>> return ep, true >>> } >>> >>> In the main entry points... >>> >>> type ThingService struct { >>> store event.Store >>> repo *thing.Repository >>> } >>> >>> func (srv *ThingService) Apply(id event.AggregateId, text string) error { >>> thing, ok := srv.repo.ById(id) >>> if !ok { return fmt.Errorf("thing doesn't exist") } >>> thing.Apply(text) >>> return srv.store.SaveChanges(thing) >>> } >>> >>> Anyways... I'm not comfortable that the Aggregate composes the current >>> state and recording of changes, but I haven't found a way to resolve that >>> nicely. >>> >>> Hopefully it gives some ideas how to improve things, but I'm not >>> convinced that either one is the best solution for Go. >>> >>> + Egon >>> >>> On Tuesday, 18 November 2014 10:23:18 UTC+2, Max Persson wrote: >>>> >>>> Thanks for pointing that out, will fix those issues. >>>> >>>> /Max >>>> >>>> On Tuesday, November 18, 2014 8:38:07 AM UTC+1, Ingo Oeser wrote: >>>>> >>>>> You might want to fix those, too: >>>>> http://go-lint.appspot.com/github.com/looplab/eventhorizon >>>> >>>> -- > > You received this message because you are subscribed to a topic in the > Google Groups "golang-nuts" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/golang-nuts/Ro4Ba-8MVOg/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > golang-nuts...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a8267a58-514c-41d3-8ab1-425235efb21cn%40googlegroups.com.