当可启动组件需要IBus时,Autofac IStartable可以和NServiceBus一起使用吗?
Can Autofac IStartable be used with NServiceBus when the startable component needs IBus?
这里的场景是有一个组件在启动时需要 运行 一些初始化代码。这是通过让代码实现 Autofac.IStartable.Start
并将代码注册为 IStartable
.
来实现的
此代码随后在多个环境中使用:几个 ASP.NET 网站、一个 NServiceBus.Host.exe
托管的 NSB 应用程序和一个基于 Atlas 的 Windows 服务。它在每个方面都运行良好。
最近的一项更改为该启动代码引入了构造函数注入依赖项,其中包括一些深度 NServiceBus.IBus
的实例。当 NServiceBus 主机中的代码现在 运行s 时,它会抛出一个 ComponentNotRegisteredException
声明 "The requested service 'NServiceBus.IBus' has not been registered."
这是 NServiceBus 主机 (v4.7) 的端点配置:
var builder = new ContainerBuilder();
builder.RegisterModule(new CoreModule());
Configure.With().AutofacBuilder(builder.Build());
似乎正在发生的事情是 IStartable.Start
方法在调用 ContainerBuilder.Build()
方法时被执行,这是可以理解的,但此时 IBus
尚未注册容器。
当消息处理程序稍后通过 NServiceBus 实例化时,并且它们依赖于 IBus
,总线被正确注入。这将表明 NServiceBus 是 'adding' 容器构建后对容器的新注册。
我更改了启动代码以实现 NServiceBus.IWantToRunWhenBusStartsAndStops
,然后它 运行 在 NServiceBus 托管应用程序中成功地执行了 Start
方法。但是,Start
方法不会从 ASP.NET 应用程序或 Windows 服务中执行。
Web应用中的NServiceBus启动代码如下:
var bus = Configure.With((typeof (CoreModule).Assembly
.GetTypes().Where(t =>
t.Namespace != null
&& t.Namespace.StartsWith("OurApp.Messages"))))
.DefaultBuilder()
.DisableTimeoutManager()
.UseTransport<Msmq>()
.PurgeOnStartup(false)
.UnicastBus()
.CreateBus()
.Start();
执行此代码,然后 bus
向容器构建器注册,如下所示:
builder.Register(cb => bus).As<IBus>().SingleInstance();
所以我的双重问题:Autofac.IStartable
仍然可以在 NServiceBus 托管应用程序中以某种方式使用,或者是否有一种方法可以使替代的通用 start-up/bootstrap 机制起作用,例如 NServiceBus.IWantToRunWhenBusStartsAndStops
?
Can Autofac.IStartable
still be used somehow in an NServiceBus hosted application?
是,但如果组件依赖于 IBus
。
Can NServiceBus.IWantToRunWhenBusStartsAndStops
be used as an alternative?
仅当您在每个应用程序中处理 NSB 消息时。在我的例子中,该网站仅向远程端点发送消息,因此未调用此接口。
我 'solution' 确保两种情况下的启动代码 运行 是双重的:
首先,在启动时需要运行的类上实现Autofac.IStartable
和NServiceBus.IWantToRunWhenBusStartsAndStops
。它们具有相同的方法签名,这很方便。
其次,仅在 NServiceBus.IWantToRunWhenBusStartsAndStops
被 未 调用的应用程序中在容器中注册 Autofac.IStartable
实现。这是通过将它们的注册拆分为一个单独的 Autofac 模块来完成的,该模块仅在这些应用程序中注册。该模块看起来像这样:
public class StartablesModule : Module
{
protected override void Load([NotNull] ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(
typeof (StartablesModule).Assembly)
.Where(t => t.IsAssignableTo<IStartable>())
.As<IStartable>();
}
}
这里的场景是有一个组件在启动时需要 运行 一些初始化代码。这是通过让代码实现 Autofac.IStartable.Start
并将代码注册为 IStartable
.
此代码随后在多个环境中使用:几个 ASP.NET 网站、一个 NServiceBus.Host.exe
托管的 NSB 应用程序和一个基于 Atlas 的 Windows 服务。它在每个方面都运行良好。
最近的一项更改为该启动代码引入了构造函数注入依赖项,其中包括一些深度 NServiceBus.IBus
的实例。当 NServiceBus 主机中的代码现在 运行s 时,它会抛出一个 ComponentNotRegisteredException
声明 "The requested service 'NServiceBus.IBus' has not been registered."
这是 NServiceBus 主机 (v4.7) 的端点配置:
var builder = new ContainerBuilder();
builder.RegisterModule(new CoreModule());
Configure.With().AutofacBuilder(builder.Build());
似乎正在发生的事情是 IStartable.Start
方法在调用 ContainerBuilder.Build()
方法时被执行,这是可以理解的,但此时 IBus
尚未注册容器。
当消息处理程序稍后通过 NServiceBus 实例化时,并且它们依赖于 IBus
,总线被正确注入。这将表明 NServiceBus 是 'adding' 容器构建后对容器的新注册。
我更改了启动代码以实现 NServiceBus.IWantToRunWhenBusStartsAndStops
,然后它 运行 在 NServiceBus 托管应用程序中成功地执行了 Start
方法。但是,Start
方法不会从 ASP.NET 应用程序或 Windows 服务中执行。
Web应用中的NServiceBus启动代码如下:
var bus = Configure.With((typeof (CoreModule).Assembly
.GetTypes().Where(t =>
t.Namespace != null
&& t.Namespace.StartsWith("OurApp.Messages"))))
.DefaultBuilder()
.DisableTimeoutManager()
.UseTransport<Msmq>()
.PurgeOnStartup(false)
.UnicastBus()
.CreateBus()
.Start();
执行此代码,然后 bus
向容器构建器注册,如下所示:
builder.Register(cb => bus).As<IBus>().SingleInstance();
所以我的双重问题:Autofac.IStartable
仍然可以在 NServiceBus 托管应用程序中以某种方式使用,或者是否有一种方法可以使替代的通用 start-up/bootstrap 机制起作用,例如 NServiceBus.IWantToRunWhenBusStartsAndStops
?
Can
Autofac.IStartable
still be used somehow in an NServiceBus hosted application?
是,但如果组件依赖于 IBus
。
Can
NServiceBus.IWantToRunWhenBusStartsAndStops
be used as an alternative?
仅当您在每个应用程序中处理 NSB 消息时。在我的例子中,该网站仅向远程端点发送消息,因此未调用此接口。
我 'solution' 确保两种情况下的启动代码 运行 是双重的:
首先,在启动时需要运行的类上实现Autofac.IStartable
和NServiceBus.IWantToRunWhenBusStartsAndStops
。它们具有相同的方法签名,这很方便。
其次,仅在 NServiceBus.IWantToRunWhenBusStartsAndStops
被 未 调用的应用程序中在容器中注册 Autofac.IStartable
实现。这是通过将它们的注册拆分为一个单独的 Autofac 模块来完成的,该模块仅在这些应用程序中注册。该模块看起来像这样:
public class StartablesModule : Module
{
protected override void Load([NotNull] ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(
typeof (StartablesModule).Assembly)
.Where(t => t.IsAssignableTo<IStartable>())
.As<IStartable>();
}
}