0

I'm using NServiceBus 3.3.3. I'm using Ninject as my container and I'm initialising the bus in an module by binding to the following method:

Bind<IBus>().ToMethod(context =>
{
    return CreateBus();
}).InSingletonScope();



private IBus CreateBus()
{
    var bus = NServiceBus.Configure.With()
    .NinjectBuilder(this.Kernel)
    .DefineEndpointName("MyEndpointName")
    .MsmqTransport()
    .IsTransactional(true)
    .PurgeOnStartup(false)
    .DisableRavenInstall()
.DisableTimeoutManager()
    .InMemorySubscriptionStorage()
    .XmlSerializer()
    .UnicastBus()
    .ImpersonateSender(false)
    .CreateBus();

    return bus.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
}

The same code works fine in a different (MVC4) project but in my WCF WAS service I seems that the transport member of UnicastBus is always null and thus line 824 transport.MaxThroughputPerSecond = license.MaxThroughputPerSecond; falls over.

Object reference not set to an instance of an object. at NServiceBus.Unicast.UnicastBus.NServiceBus.IStartableBus.Start(Action startupAction) in c:\TeamCity\buildAgent\work\nsb.master_2\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 824 at Access.Cloud.WebService.Modules.NServiceBusModule.CreateBus() in l:\Projects\aCloud\InsightIntegration\Access.Cloud.WebService\Modules\NServiceBusModule.cs:line 47 at Access.Cloud.WebService.Modules.NServiceBusModule.b__0(IContext context) in l:\Projects\aCloud\InsightIntegration\Access.Cloud.WebService\Modules\NServiceBusModule.cs:line 25 at Ninject.Activation.Provider'1.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Provider.cs:line 38 at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157 at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) at System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()

I've checked it in the debugger too and sure enough transport is null.

I'm guessing it's something environmental but I assume the transport just comes from some bindings that get set up when MsmqTransport() is called. I tried moving the code that loads the module from the Ninject web bootstrapper to Global.asax but it didn't make a difference.

Any help or guidance appreciated!

Steven
  • 166,672
  • 24
  • 332
  • 435
mackie
  • 4,996
  • 1
  • 17
  • 17
  • I thought I'd add that it seems to be unrelated to the type of builder used and it does exactly the same thing when `DefaultBuilder()` is used. – mackie Dec 18 '12 at 11:56
  • I wonder if WAS is causing issues with the assembly scanning. Can you try to pass a list of relevant assemblies explicitly to Configure.With()? – Andreas Öhlund Dec 18 '12 at 21:44
  • @AndreasÖhlund This problem seems to have gone away since I updated to 3.3.4 and changed the endpoint in question to SendOnly. If I have similar problems in future I'll try the explicit method. Thanks for your help :) The solution is up and running in integration testing now and works like a charm :D – mackie Jan 30 '13 at 15:04

1 Answers1

3

The issue is that you're using that method to create your reference to the bus. The method you're using should be called once at process startup and that's it.

The fix would be to store the bus variable in a field on that class, and then use that field in your container registration like this:

Bind<IBus>().ToMethod(context =>
{
    return bus;
}).InSingletonScope();
Udi Dahan
  • 11,932
  • 1
  • 27
  • 35
  • Thanks for the quick response Udi. It doesn't seem to matter how I do it, it happens independently of the container it seems. I changed my code to the above (I was keeping a static reference to it anyway) and it still happened. Most puzzling! – mackie Dec 18 '12 at 16:53
  • Samples work and the bus initialises ok in another web project in the same solution. – mackie Dec 19 '12 at 15:41
  • I also created a test WCF service project from scratch which also works. On a semi-related note it looks like passing an existing kernel to NinjectBuilder will create the IBus binding so the call to Bind in my code is not needed (and indeed causes problems when Ninject comes to resolve IBus). – mackie Dec 19 '12 at 15:54