oop - Detach event listeners for domain events? or how to stop executing otherwise required post events on specific use-cases -
so let's take usual order example. assuming rich domain model have order.place() call. seems way additional tasks related action these days point domain events. let's call fires "orderplaced" event. usual thing happens after event placed send confirmation email create event listener event, , send email.
so simply: order.place() > orderplaced event raised > emailfororderplaced listener fires > email gets sent
we have registration works in similar way (user.register() > userregistered event raised > registration listener fires > email gets sent)
however:
the problem (a made task - doesnt have make sense - lot of real business requirements don't anyway):
now want offer registration + order functionality in one, , opposed regular 1 email per registration + 1 email order, want ot send 1 email contains both. aggergated concern create domain service this, if call user.register(); order.place(); fire 2 events normally, spamming customer emails (ok, not really, example)
so how around this? sending combined email not problem because can raise event in service, still leaves original 2 emails. if detach 2 listeners in service before execute 2 calls, mean have know functionality , every time new 1 gets added have go service detach 1 well, etc, there better way seamlessly this?
you have few options.
first of all, make use-case explicit. can, example, add bool userregistered event indicating user registered part of creation of order. allow email handlers send appropriate emails.
another option create handler sends emails both events. since emails shouldn't sent anyway have handler, upon commit, determine events have arrived during given unit of work , in way, determine type of email send. if both events have arrived, send single email, otherwise send email corresponding event received. work, have make sure handlers have per-unit-of-work lifetime.
finally, digging deeper, observe have aggregates @ play, user , order. ideally, in distributed scenarios, shouldn't modify aggregates within single transaction. implement use-case requiring modification of aggregates, create saga known process manager. saga, each aggregate gets modified in own transaction , part of transaction , message sent advance next step (in case there 2 steps). saga receive initiating message called registeruserandcreateorder. register user, order, , upon completion of both, send appropriate email. note user , order can created concurrently. take here more on event driven approach.
Comments
Post a Comment