解决服务总线依赖性。轨道交通
Resolving service bus dependency. MassTransit
从控制器发布消息的最简单方法是在 Global.asax.cs:
中输入注册码
public class MvcApplication : HttpApplication {
protected void Application_Start() {
Bus.Initialize(sbc => {
sbc.UseRabbitMq();
sbc.ReceiveFrom("rabbitmq://localhost/commands_webui");
});
}
}
并在这样的控制器中调用代码:
public class OrdersController : Controller {
public ActionResult AddOrderLine(OrderLine input) {
var command = SOME_OO_MAPPER<AddOrderLineCommand>(input).Map();
Bus.Instance.Publish<AddOrderLineCommand>(command);
return View();
}
}
- 是否使用 SimpleInjector(或任何其他 IoC 容器 解决 MassTransit 总线依赖性) 比所描述的方法有什么优势?
合理还是只会增加复杂性?
- 将基本控制器与注入的服务总线实例一起使用是否合理?
- MassTransit 定义了它自己的
IServiceBus
接口。通过这种方式解决服务总线依赖是否正常?
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?
我想说的是,您应该始终支持构造函数注入而不是直接将总线用作 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,这允许您将核心应用程序逻辑与任何使用的第 3 方库分离。
使用构造函数注入不会增加复杂性;您的 class 具有相同数量的依赖项。最大的区别在于,这更加灵活和透明。
Is it reasonable to use a base controller with injected service bus
instance?
Base classes 是许多人的代码味道,我什至会说它是一种反模式,以防它们用于包含一组常用的依赖项。他们试图隐藏 class 需要太多依赖项的事实,而不解决根本问题,即 Single Responsibility Violation。防止像这样使用基本 classes,因为它会使这些违规行为像拇指一样突出。
MassTransit defines its own IServiceBus interface. Is it normal to
resolve service bus dependency via this type?
正如我上面所说,防止您的应用程序代码依赖于 Masstransit 库本身。这引入了供应商锁定。您的应用程序代码(Composition Root 除外)不应该知道它使用的外部库的任何信息。这适用于日志库、DI 库、消息总线库;你的名字。这样做符合 Interface Segregation Principle 的规定,即客户端应该定义抽象。通过依赖注入,防止这种耦合真的很容易(也很愉快)。
从控制器发布消息的最简单方法是在 Global.asax.cs:
中输入注册码public class MvcApplication : HttpApplication {
protected void Application_Start() {
Bus.Initialize(sbc => {
sbc.UseRabbitMq();
sbc.ReceiveFrom("rabbitmq://localhost/commands_webui");
});
}
}
并在这样的控制器中调用代码:
public class OrdersController : Controller {
public ActionResult AddOrderLine(OrderLine input) {
var command = SOME_OO_MAPPER<AddOrderLineCommand>(input).Map();
Bus.Instance.Publish<AddOrderLineCommand>(command);
return View();
}
}
- 是否使用 SimpleInjector(或任何其他 IoC 容器 解决 MassTransit 总线依赖性) 比所描述的方法有什么优势? 合理还是只会增加复杂性?
- 将基本控制器与注入的服务总线实例一起使用是否合理?
- MassTransit 定义了它自己的
IServiceBus
接口。通过这种方式解决服务总线依赖是否正常?
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?
我想说的是,您应该始终支持构造函数注入而不是直接将总线用作 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,这允许您将核心应用程序逻辑与任何使用的第 3 方库分离。
使用构造函数注入不会增加复杂性;您的 class 具有相同数量的依赖项。最大的区别在于,这更加灵活和透明。
Is it reasonable to use a base controller with injected service bus instance?
Base classes 是许多人的代码味道,我什至会说它是一种反模式,以防它们用于包含一组常用的依赖项。他们试图隐藏 class 需要太多依赖项的事实,而不解决根本问题,即 Single Responsibility Violation。防止像这样使用基本 classes,因为它会使这些违规行为像拇指一样突出。
MassTransit defines its own IServiceBus interface. Is it normal to resolve service bus dependency via this type?
正如我上面所说,防止您的应用程序代码依赖于 Masstransit 库本身。这引入了供应商锁定。您的应用程序代码(Composition Root 除外)不应该知道它使用的外部库的任何信息。这适用于日志库、DI 库、消息总线库;你的名字。这样做符合 Interface Segregation Principle 的规定,即客户端应该定义抽象。通过依赖注入,防止这种耦合真的很容易(也很愉快)。