0

Im having some problems with NServiceBus, I can get the pubsub example working fine, but now I'm trying to integrate it into a production project and I cant get the thing to work!

My publisher code is exactly the same as the publisher example (I've just imported the project to rule out any other issues) but I then create a void function and call it from my WPF app and I get a "you cant call bus without creating an instance of bus" error

 public void RunTest()
            {
                    var eventMessage = new MarketPriceMessage();
                    eventMessage.Ticker = "IBM";
                    eventMessage.DataType = "Bid";
                    eventMessage.Value = (decimal)23.23423;
                    eventMessage.EventId = Guid.NewGuid();
                    eventMessage.Time = DateTime.Now; // > 30 ? (DateTime?)DateTime.Now : null;
                    eventMessage.Duration = TimeSpan.FromSeconds(99999D);



                    Bus.Publish(eventMessage);
            }

Any ideas as to whats going on there and where I'm going wrong?

Following @Adam's comments below this is the code I'm using internally in my WPF App:

    public partial class App : Application
{
    public IBus bus { get; set; }

     protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        NServiceBus.Configure.With()
               .Log4Net()
               .SpringBuilder()
               .XmlSerializer()
               .MsmqTransport()
               .UnicastBus()
               .LoadMessageHandlers()
               .CreateBus()
               .Start();
    }
}

}

and

namespace WpfApplication2
{
    class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher { }

}

and

namespace WpfApplication2
{
    public class SubscriptionAuthorizer : IAuthorizeSubscriptions
    {
        public bool AuthorizeSubscribe(string messageType, string clientEndpoint, string clientWindowsIdentity, IDictionary<string, string> headers)
        {
            return true;
        }

        public bool AuthorizeUnsubscribe(string messageType, string clientEndpoint, string clientWindowsIdentity, IDictionary<string, string> headers)
        {
            return true;
        }
    }
}

App Config

<configuration>
  <configSections>
    <section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core"/>
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core"/>
  </configSections>

  <MsmqTransportConfig 
                       InputQueue="WpfApplication2InputQueue" 
                       ErrorQueue="error" 
                       NumberOfWorkerThreads="1" 
                       MaxRetries="5"/>
  <UnicastBusConfig>
    <!--DistributorControlAddress="" DistributorDataAddress="" ForwardReceivedMessagesTo="">-->
    <MessageEndpointMappings>
    </MessageEndpointMappings>
  </UnicastBusConfig>

When I'm stepping through my code I can see that bus is a null object.

I am including the references as normal

Brad Werth
  • 17,411
  • 10
  • 63
  • 88
Chris Allison
  • 73
  • 1
  • 10
  • Are you bootstrapping NSB in your WPF app some where? With WPF you will be self-hosting and therefore need to build up NSB on your own. – Adam Fyles Jun 27 '11 at 14:46
  • How would one do that? I have been trying for nearly a week on this! The latest message I'm getting is that it cant find a endpoint configuration file but everything is in the exe! – Chris Allison Jun 28 '11 at 19:43

2 Answers2

1

I'm not too familiar with WPF, but it looks like there is an Application.Startup event that may work. You need to "manually" configure the bus as shown here in the docs

Peter
  • 7,792
  • 9
  • 63
  • 94
Adam Fyles
  • 6,030
  • 1
  • 23
  • 29
  • thanks, there is that event but I when I try that method I get a null bus instance, it doesnt look like NSB is injecting the object? I've tried this in worker classes as well. – Chris Allison Jun 29 '11 at 07:31
  • Can you post the code you are using to bootstrap? Sounds like you may be missing something simple. – Adam Fyles Jun 29 '11 at 12:10
  • I think I've figured it out!!!!! I wasnt starting the the class that held all the NSB stuff, I was just calling it after instantiating it. I guess IWantToRunAtStartUp doesnt get called when you call the class constructors? I guess I've got to leave the generic NSB host running in a loop while my app does stuff and publishes when it requires? Is there a best practise here? – Chris Allison Jun 29 '11 at 18:53
  • Yes, you have to hang on to a reference to IBus somewhere globally. If you are using a container you could use that same container for NSB. – Adam Fyles Jul 01 '11 at 00:42
  • Yeah I think my problem was not really understanding Dependency injection, but I've got it to work pretty much now so will cross that bridge later! – Chris Allison Jul 01 '11 at 14:37
0

If you're not using Autofac or some other container, the problem is you skipped the assignment to your bus variable. I normally put this in Global.asax Application_Startup, but this way should work too.

If you are using a container, and you register the class that implements your ServiceContract, you can get away with having a local IBus constructor/property injected when it's instantiated.

public IBus bus { get; set; }

protected override void OnStartup(StartupEventArgs e)
{
   base.OnStartup(e);

   bus = NServiceBus.Configure.With() // keep a reference to the returned bus. 
           .Log4Net()
           .SpringBuilder()
           .XmlSerializer()
           .MsmqTransport()
           .UnicastBus()
           .LoadMessageHandlers()
           .CreateBus()
           .Start();
}
SDShooter
  • 103
  • 6