This project is read-only.

Event Publisher Implementation

Nov 27, 2013 at 3:11 AM
Edited Nov 27, 2013 at 12:14 PM
Hi Steven,

I know we've had a similar conversation before here. And I've got all of that (more or less), but I finally figured out what is bugging me about it all. What does the event publisher look like? My Publisher is a static class that calls this Dispatcher. My Dispatcher looks like this and it works but...
    public class SimpleInjectorDomainEventDispatcher : IEventDispatcher
    {
        private readonly Container _container;

        public SimpleInjectorDomainEventDispatcher(Container container)
        {
            _container = container;
        }

        public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
        {
            var handlers = _container
                .GetAllInstances<IDomainEventSubscriber<TEvent>>();

            foreach (var item in handlers)
            {
                item.HandleEvent(eventToDispatch);
            }

        }
    }
It seems like it removes the need for your MultipleDispatchEventHandler here. Do you mind sharing your thoughts?
Nov 27, 2013 at 12:15 PM
I've updated this to make more sense (hopefully). I was too tired when I entered it last night. Hopefully you can shed some light on the subject.
Nov 27, 2013 at 12:38 PM
Edited Nov 27, 2013 at 12:38 PM
Hi Steven,

My idea of letting event publisher depend on an IEventHandler<T> directly instead of a non-generic IEventDispatcher is that the former makes it very clear what events a consumer publishes. In that case, publishing a new event means changing the constructor and means changing a factory method in your unit tests. In other words it forces you to change a test, which I usually think is good.

There's however another school of though that just doesn't want the unit tests to be this strict. When using the IEventDispatcher, letting a consumer publish an extra event means that all existing unit tests would still succeed, and why shouldn't they? The only thing left to do is add an extra test that checks whether the consumer publishes the new event under the given conditions but ignoring any other event that might be published.

There's a lot to say about this last approach. I think the main question is: should the contract of a class state which events it publishes, or should it just state the fact that it publishes events?

The choice is up to you :-)
Nov 27, 2013 at 12:56 PM
ah! I will say it back to you in my words to confirm my understanding. Because in your world the dependency on an event handler is passed in there's no need for a Publisher. The publisher is the owner of the event and it calls back on the passed in interface to raise the event.

If I'm correct about what you are saying I'll have to think on it a bit. In some ways I like it, but I'm in the second camp at least on this project. That being said see anything 'wrong' with my implementation?
Nov 27, 2013 at 1:28 PM
There's nothing wrong with your implementation.

I try to get my dependency graph strict and verifiable and that's one reason for me to have the dependencies very explicit. The problem with the IEventDispatcher is that it breaks the dependency graph by delaying the creation of event handlers and this disallows the container from verifying the complete graph. But the thing is, even if you inject event handlers directly, it's impossible to verify whether all event handlers are registered, since it is valid to have no event handler for an event (in that case a MultipleDispatchEventHandler<T> is still injected). So the graph is always valid, which makes injecting IEventHandler<T> implementations directly for reasons of verification useless.
Nov 27, 2013 at 2:04 PM
Thank you! Much clearer now, and I'll consider your approach in another project. Time will tell which I like better. Don't be surprised if I don't come back to you again on the topic.
Nov 27, 2013 at 2:22 PM
I won't be surprised and feel free to do so; that's what this forum is for.
Dec 30, 2013 at 2:30 AM
hi Steven,

I've now had some time to give this some thought and as I thought, I have some more questions.

In my current hot project we have a set of Aggregate Root objects. Each Root has some interesting Domain Events that it raises to let other Roots know they something has changed and the 'subscribing' Root needs to do something interesting too. The subscribing Root may also raise some events to share with others etc. In addition the users want to know about most of these interesting events via email (or Notification box or something). My understanding of the principles of Aggregate Root is that they really should not be modified in the same transaction. Using a bus, this (different transactions) is relatively easy to achieve but the Bus I'm familiar with (NServiceBus) doesn't recommend using a web site as a publisher (for various reasons all of which make sense to me). Please can you reply about the following
  1. How are you achieving (or are you even concerned with) modifying separate roots in different transactions. Using your methods of decorators I can see how I could make sure that each EventHandler got wrapped in a new transactionscope and that would do the trick. The issue with that of course is that if there is a failure you are left in an inconsistent state. If they all use the same transactionscope your scalability goes to hell does it not?
  2. Using a Bus for the initial endpoint of all my commands solves the above as long as I am very careful about designing for eventual consistency and task based UI. Easy to say, not easy to do (IMO). Do you have some feedback or thoughts on approach that you take?
Steven
Dec 30, 2013 at 12:54 PM
Well, the Simple Injector forum is probably not the best way to discuss this, and I must say I'm not an expert on messaging and DDD.

If I'm not mistaken, it would be possible for two aggregate roots to operate in one single transaction. The example that comes to my mind is that of a banking application where an BankAccount is the aggregate root. The TransferMoney use case always needs two accounts (the debet and the credit account) and this operation must be transactional. This is an example about DDD I've seen long ago, but perhaps this example is flawed.

Events on the other hand will typically be something that does not belong to the core operation. If you're sending a mail message when someone got a new deposite on its bank account, this does not have to operate in that transaction. As a matter of fact, when the mail could not be sent, this should not influence the transfer money transaction.

But even though sending the mail could fail, the intend of the event should never get lost. The only way to do this reliably is by storing those events in a transactional queue where writing the events to the queue happens in the same transaction as where the core use case (the transfer money) is operated it. Only after the transaction is commetted (and the events are in that queueu) they can be picked up for processing. This ensures that events can't get lost. Once a event is picked up to be processed by an EventHandler, you can wrap this operation again in a transaction, since the action of one single event handler should probablt be transactional as well.

If I'm not mistaken, this is the exact approach the NServiceBus takes. It uses a TransactionScope to ensure that writing events to MSMQ is done within the same transaction as where the command is executed.

> Easy to say, not easy to do (IMO).

I would say that is absolutely true. Not easy.
Marked as answer by dot_NET_Junkie on 3/2/2014 at 11:18 AM
Dec 30, 2013 at 1:26 PM
Edited Dec 30, 2013 at 2:08 PM
Well, the Simple Injector forum is probably not the best way to discuss this, and I must say I'm not an expert on messaging and DDD.
True, but I couldn't find the "Ask Steven about other topics you are interested in" forum so this was it. LOL!! Since a lot of what I'm doing on this project is very oriented to the same approach you discuss on your blog and simple injector is well suited to I wanted to get an insight into what you do in these situations.

The example you cite is a good one that I hadn't thought of, but perhaps that could be modeled out by abstracting the transaction into it's own root... Regardless it could work under a single transaction. I was worried about the case where the event handlers caused other events (and therefore handlers). The transaction seems to get pretty big at that stage. Granted, its not like thousands of Big Ball of Mud projects everywhere (many of which I've been part of) don't do that sort of thing... Still have you tackled such scenarios?

Next time I will use your blog for such queries.
Dec 30, 2013 at 2:35 PM
> I couldn't find the "Ask Steven about other topics you are interested in" forum so this was it.

LOL! Another great place to ask these type's of questions is Stackoverflow. DDD, Dependency Injection, and event handling are topics that are discussed regularly on Stackoverflow. This is usually a better place to discuss these things than my blog. But if you want to make sure I read that question, send me a private message through CoderPlex with a link to the question, or send me a mail.