Question

I've a delicate problem regarding the fact that I have a working solution with AutoFac, CommonServiceLocator and Udi's Domain events (http://www.udidahan.com/2009/06/14/domain-events-salvation/). I let Autofac set the ServiceProvider in MVC bootstrapper. But two things are annoying me: 1) The domain events are raised through static method which uses CommonServiceLocator. This makes it hard to unit test and it also hides away some Autofac features I like to use. This leads me to ... 2) My events are consumed by IEventSubsriber where T is a DomainEvent. But the scenario is that I like to have several subscribers on one event. That means I get several Subscriber when I raise an Event.

 IEnumerable<IEventSubscriber<T>> registeredHandlers =
                    ServiceLocator.Current.GetAllInstances<IEventSubscriber<T>>();

But I have tagged this Subscriber Instances with MetaData through AutoFac:

   builder.RegisterType<CreateNewRevisionEvent>().AsImplementedInterfaces()
                   .WithMetadata<EventSubsriberMetadata>(x => x.For(order => order.Order, 1));

and the MetaData Class is:

public class EventSubsriberMetadata
    {
        public int Order { get; set; }
    }

So the question. I would like to accomplish that I can get somehow use a Abstract Factory (do not solve 1) is just move the problem to another place), AutoFac Delegate Factory (Func<> not that happy with Generics) or just a plain and simple injection into a DomainEventDispatcher?

What's killing me is that I would like to avoid dependencies in Domain.Core assembly. I know that I have a dependency to CommonServiceLocator today. But use DI on an Base Entity class (that what it result in) I do not know any easy way. I've seen Nicklas Blumhardt's demo where AutoFac injects an DomainEventDispatcher into entities through NHibernate Interceptors and there for can dispatch Events during Up/Down to persistence. Neat Solution. But I use Entity Framework 5 and also I hope for a easier solution.

Looking forward to see some answer or at least discuss this topic. I think a lot of people halts when they approach this problem. And maybe just - "Ok we use CSL just for Events" and they make boundaries for Unit testing as well. - "We skip unit testing for events". That not an issue here :)

/Best Regards Magnus

Was it helpful?

Solution

Your quest boils down to decoupling your domain code from dependencies such as Autofac, CommonServiceLocator. That is a good thing. That said, there is nothing inherently wrong with having a service locator (the domain event registry & raise) in your domain code embedded. You just have to be at peace with the decreased discoverability. There are other ways of achieving a similar goal (e.g. Plain .net events, IObservable entities, ...). The subscriptions should happen from the outside. For example as part of the creation of a child lifetime scope.

Another thing to consider is when the events should be fired. If you're okay with a little bit of latency, you could have the entities collect their domain events internally, and at the end of the operation ask the entities for their collected domain events, dispatching them then and there to the subscribers. Note how this last part could happen in the application layer or at least outside of the domain code. A lot depends on what you're trying to achieve within the event subscribers.

So decoupling is certainly possible, but it requires validating the strategy taken against your requirements. Experiment :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top