The simplest way to publish a message from a controller is to have a registration code in Global.asax.cs:
public class MvcApplication : HttpApplication {
protected void Application_Start() {
Bus.Initialize(sbc => {
sbc.UseRabbitMq();
sbc.ReceiveFrom("rabbitmq://localhost/commands_webui");
});
}
}
and calling code in a controller like that:
public class OrdersController : Controller {
public ActionResult AddOrderLine(OrderLine input) {
var command = SOME_OO_MAPPER<AddOrderLineCommand>(input).Map();
Bus.Instance.Publish<AddOrderLineCommand>(command);
return View();
}
}
IServiceBus
interface. Is it normal to resolve service bus dependency via this type?Does resolving the MassTransit bus dependency with SimpleInjector (or with any other IoC container) have any advantages over the described approach? Is it reasonable or would it only increase complexity?
I would say that you should always favor constructor injection over using the Bus directly as an Ambient Context. Using constructor injection has the advantage that it makes it really clear what the class'es dependencies are. I would even prevent using a Bus
class or IServiceBus
abstraction from the MassTransit directly in your code, but instead define your own abstraction (even if it is the same) and register a proxy implementation that maps directly to MassTransit
. Your message bus should be an implementation detail and your application should not have to take a dependency on it. This way you adhere to the Dependency Inversion Principle, which allows you to decouple your core application logic from any used 3rd party libraries.
Using constructor injection does not increase complexity; your class has the same number of dependencies. The big difference is, that this is more flexible and transparent.
Is it reasonable to use a base controller with injected service bus instance?
Base classes are a code smell by many and I would even say its an anti-pattern in case they are used to contain a set of commonly used dependencies. They try to hide the fact that a class needs too many dependencies, without solving the root issue, i.e. a Single Responsibility Violation. Prevent using base classes like this, because it will make these violations stick out like a sore thumb.
MassTransit defines its own IServiceBus interface. Is it normal to resolve service bus dependency via this type?
As I said above, prevent your application code from taking a dependency on the Masstransit library itself. This introduces a vendor lock-in. Your application code (except for your Composition Root) shouldn't have to know anything about the external libraries that it uses. This holds for logging libraries, DI libraries, message bus libraries; you name it. Doing so conforms to the Interface Segregation Principle that states that the client should define the abstraction. And with Dependency Injection it is really easy (and pleasurable) to prevent this coupling.