Reputation: 8289
What are the options or any best practice ways of doing cross-Bounded Context (BC) communication
with Domain Events
that can use Dependency Injection (DI)
to create the Event Handlers
in the receiving BC? The BC's are in the same LAN but on separate servers etc. Ideally there should be one endpoint in each BC which would instantiate the correct Event Handler via DI as needed, instead of having one listener per event/event handler.
Something like this simple example would be simple with DI and local Event Handlers with minimal effort, however once you are on other servers with either http, tcp, Message Queues etc. it requires considerably more effort and/or libraries to ease the plumbing.
This would be for a C# .NET environment.
Upvotes: 1
Views: 1808
Reputation: 2296
I think you can do Udi's style if you want to. I believe you probably want to mix local Domain Events with Cross-bounded Context events? If that so you I guess the desired execution is that the Source BC will raise an event like "OrderIsShipped"
. This Domain event can have a local EventSubscriber
public class SendNotificationWhenOrderIsShipped : IEventHandler<OrderIsShipped>
{
...
Handle(...)
}
in Source BC application layer. But however your BC's app layer should be aware if this is publish out on a "Bus".
Maybe a DomainEventBusPublisher
class?
There are several ways of doing this.
You could have another PublishOrderIsShipped
class that also Implements interface IEventHandler<OrderIsShipped>
. This class just publish (serialize) event to an NServiceBus EndPoint or a RabbitMQ End Point. Here it is a classic Publish/Subscribe approach that is the best way to go. Event is published in a fire-and-forget way which means the publisher is not aware of who is subscribing.
You could Decorate The SendNotificationWhenOrderIsShipped
event handler with an IoC container (Generic Decorator) and publish event to queue like above. Drawback is that you actually need a event handler to decorate. If there is no event handler then you have to come up with one... which feels forced in some way. But if the application wants to act locally on each domain event that are supposed to be publish to other BC, this approach can be away to go...
You can implement a
public class BlaBlaBlaDomainEventPublisher : IEventPublisher<OrderIsShipped>
But the beauty here is that you can Do a generic instead...
public class EventPublisher<T> : IEventPublisher<T>
Here you can inject your RabbitMQ or NServiceBus wrapper into EventPublisher
. Then you can close the Open Generic EventPublisher if you want to make some Custom actions. BUT my recommendation is to not try do close it. Better if you can keep this pure SOLID and decorate EventPublisher
with for example Error handling or republishing or Saga handling.
But this last approach requires that your static DomainEvents.Raise(...)
method also look in your IoC container if there is any EventPublishers
registered.
Maybe this will help you in some way?
Upvotes: 1