NServiceBus Dependency Injection not working for Saga Timeouts -
i having problems getting nservicebus 4.6.1 dependency injection working saga timeouts. using self-hosting in asp.net web application , have property injection setup. works when messages sent web controllers however, when timeout message handled in saga same di property not being set , null.
here key bits of setup:
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(); } }
saga class
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 fine myinjectedservice.dosomething(message); } public void timeout(sometimeout state) { // here myinjectedservice null myinjectedservice.dosomething(state); }
}
i have tried solutions found here, here , here none of them fixed issue.
i figured out problem here. dependency injection not working in saga's timeout handler because castle.windsor lifestyle set lifestyleperwebrequest, e.g.:
public class windsorservicesinstaller : iwindsorinstaller { public void install(iwindsorcontainer container, iconfigurationstore store) { container.register( component.for<dependentservice>() .lifestyleperwebrequest() ); } }
after changing lifestyle lifestyletransient started working. of other 'non web request' lifestyles should work here.
in our setup nservicebus host running under web application , regular message handlers fine because being called in controller action, e.g.:
[httppost] public actionresult dosomething( int myid) { _bus.send( "mybus", new somemessage { myid = something.myid } ); return view(); }
when saga handles somemessage message must still part of web request , windsor resolves dependency normal. however, timeouts fired time later (in case 5 minutes) not part of web request. windsor not able resolve dependentservice object , stays null.
Comments
Post a Comment