"It's getting there."
SeptaBus is an implementation of the Mediator Pattern: it decouples messages from the code that handles the messages, keeping your code clear and simple with few dependencies so you can focus on expressing your domain logic instead of how to structure your domain logic.
In SeptaBus, there are two types of messages:
- Commands, which tell the system to do something. Commands should have exactly 1 handler.
- Events, which indicate that something has happened. Events may have 0 to many handlers.
Messages are handled by message handlers (which implement IHandler<T>
). Messages are connected to their handlers via a DI container. At present, only StructureMap is supported but adding support for additional containers is pretty easy.
SeptaBus provides the ability to add contextual information to messages via decorators. Included out-of-the-box are the following decorators, which take care of common cross-cutting concerns:
TimeStampDecorator
- Adds a timestamp to theOn
header indicating when the message was sent/published on the bus.UserNameDecorator
- Adds the current user's name to theBy
header. (You'll need to write a quick implemnentation ofIUserNameProvider
, which may be as simple asreturn HttpContext.Current.User.Identity.Name;
.RolesDecorator
- Adds the roles that the current user is a member of to theRoles
. (You'll need to write a quick implementation ofIRolesProvider
which may be as simple asreturn Roles.GetRolesForUser();
// This is a command. Sending it on the bus tells the system to submit
// the order with the supplied id.
public class SubmitOrder : ICommand
{
public Guid Id { get; set; }
}
// This is the controller that gets hit when the user clicks the
// Submit Order button in the UI.
public class OrderController : Controller
{
private IBus _bus;
// ctor...
[HttpPost]
public ActionResult Submit(Guid id)
{
_bus.Send(new SubmitOrder { Id = id });
// maybe redirect the user to a confirmation page...
}
}
// This is the handler for the SubmitOrder command.
// Each command should have exactly 1 handler - no more, no less.
public class SubmitOrderHandler : IHander<SubmitOrder>
{
private IBus _bus;
pubic void Handle(SubmitOrder message)
{
// change the order status to Submitted, save changes to the db
_bus.Publish(new OrderSubmitted { Id = message.Id });
}
}
// This is the event that gets published when an order is successfully submitted.
public class OrderSubmitted : IEvent
{
public Guid Id { get; set; }
}
// This is an event handler for the OrderSubmitted event.
// Events may have 0 to many handlers.
public class OrderSubmittedHandler : IHandler<OrderSubmitted>
{
public void Handle()
{
// send the customer an email
}
}
The architecture of SeptaBus is influenced by the writings of Udi Dahan, creator of NServiceBus.