NServiceBus依赖注入不能为Saga超时工作



我在获得NServiceBus 4.6.1依赖注入与Saga超时工作时遇到问题。我在ASP中使用自托管。. NET web应用程序,并有属性注入设置。当从web控制器发送消息时,它可以工作,但是,当超时消息在saga中处理时,相同的DI属性没有被设置并且为空。

以下是设置的关键部分:

Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{

public static IWindsorContainer Container { get; private set; }
    protected void Application_Start()
    {
        ConfigureIoC();
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        DeviceManagerDbInitializer.Instance.InitializeDatabase();
        ConfigureNServiceBus();
    }
    protected void Application_End()
    {
        if (Container != null)
        {
            Container.Dispose();
        }
    }

    private static void ConfigureIoC()
    {
        Container = new WindsorContainer()
            .Install(FromAssembly.This());
        var controllerFactory = new WindsorControllerFactory(Container.Kernel);
        ControllerBuilder.Current.SetControllerFactory(controllerFactory);
        GlobalConfiguration.Configuration.DependencyResolver
            = new WindsorDependencyResolver(Container);
    }

    private void ConfigureNServiceBus()
    {
        Configure.ScaleOut(s => s.UseSingleBrokerQueue());
        Configure.Instance.PeekInterval(500);
        Configure.Instance.MaximumWaitTimeWhenIdle(2000);
        Feature.Enable<TimeoutManager>();
        Feature.Enable<Sagas>();
        IStartableBus startableBus = Configure.With()
            .DefineEndpointName("MyQueue")
            .CastleWindsorBuilder(Container) //using NServiceBus CastleWindsor 4.6.1
            .UseTransport<AzureStorageQueue>()
            .UseAzureTimeoutPersister()
            .AzureSagaPersister()
            .PurgeOnStartup(false)
            .UnicastBus()
            .LoadMessageHandlers()
            .RunHandlersUnderIncomingPrincipal(false)
            .Log4Net(new DebugAppender { Threshold = Level.Warn })
            .RijndaelEncryptionService()
            .CreateBus();
        Configure.Instance.ForInstallationOn<Windows>().Install();
        startableBus.Start();
    }
}

传奇类

public class MySaga: Saga<MySagaData>,
    IAmStartedByMessages<StartMySagaCommand>,
    IHandleMessages<SomeMessage>,
    IHandleTimeouts<SomeTimeout>
{
    public DependentService MyInjectedService {get; set;}
    public override void ConfigureHowToFindSaga()
    {
        ConfigureMapping<StartMySagaCommand>( message => message.MyId).ToSaga( saga => saga.MyId );
        ConfigureMapping<SomeMessage>( message => message.MyId).ToSaga( saga => saga.MyId );
        ConfigureMapping<SomeTimeout>( message => message.MyId).ToSaga( saga => saga.MyId );
    }
    public void Handle(SomeMessage message)
    {
        // Here MyInjectedService is fine
        MyInjectedService.DoSomething(message);
    }
    public void Timeout(SomeTimeout state)
    {
        // Here MyInjectedService is always null
       MyInjectedService.DoSomething(state);
    }

}

我已经尝试了这里,这里和这里的解决方案,但没有一个解决问题。

我找到了问题所在。依赖注入不能在Saga的超时处理程序中工作,因为Castle。温莎的生活方式设置为LifestylePerWebRequest,例如:

public class WindsorServicesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register( Component.For<DependentService>()
                                         .LifestylePerWebRequest() );
    }
}

将Lifestyle改为LifeStyleTransient后,它开始起作用。任何其他"非web请求"的生活方式都应该在这里工作。

在我们的设置中,NServiceBus主机在web应用程序下运行,常规消息处理程序很好,因为它们是在控制器动作中调用的,例如:

[HttpPost]
public ActionResult DoSomething( int myId)
{
    _bus.Send( "MyBus", new SomeMessage { MyId = something.MyId } );
     return View();
}

当saga为此处理SomeMessage消息时,它必须仍然是web请求的一部分,并且Windsor照常解析依赖关系。然而,超时会在一段时间后被触发(在本例中是5分钟),因为它们不是web请求的一部分。Windsor不能解析DependentService对象,所以它保持为空。

最新更新