Archive for the ‘NServiceBus’ Category


You are currently browsing the archives for the NServiceBus category.

Archives

  • Categories

  • Getting Started With NServiceBus: Part 4 Integrating With StructureMap

    Wednesday, November 4th, 2009

    Here are the links to the previous posts in this series:

    Part 1 Unicast Messaging.
    Part 2 Publishing and Subscribing.
    Part 3 Sagas
    Part 4 Integrating With StructureMap

    Out of the box NServiceBus uses the Spring.Net framework IOC container. However if you want to integrate NServiceBus into your application this does not mean that you are limited to choosing Spring.Net as your container as NServiceBus allows you to plugin your IOC container of choice.

    Currently  the Beta 2 version supports the following IOC containers.

    • Unity
    • Structuremap
    • Castle
    • Autofac

    In this example I will walk you through the steps to get NServiceBus working with StructureMap.

    The first thing  you must do is reference the NServiceBus.ObjectBuilder.StructureMap.dll.  If you download NServiceBus you will find this assembly in the \binaries\containers\structuremap folder. Once you have done this you can initialize your StructureMap container in pretty much the same way as you normally would. Once you have done that you can then initialize NServiceBus like this passing in the instance of your container:

               Configure.With()
                    .StructureMapBuilder(container)
                    .... Rest of Configuration Goes Here......
    

    If any of your classes need to access the Bus to publish or send a message an instance of IBus must be injected into your class by your IOC container. However if you try to use constructor injection on your container, StructureMap will complain that it does not have a default instance defined for IBus especially if you have unit tests over your registry that work in isolation of NServiceBus.

    The best way to get round this is on the classes that need to interact with the bus to have a public property of type IBus and use property injection to inject our instance of the Bus once NServiceBus has been initialized.

    In StructureMap there are a number of different approaches to doing property injection including marking up properties with StructureMap attributes, however the technique that I favour which I unashamedly stole from Jeremy Miller’s StoryTeller project works as follows:

    On the class that you wish to access the Bus you add a public property of type IBus

     public IBus Bus { get; set; }
    

    The class should also implement the empty marker interface INeedBuildUp

    Now in our StructureMap registry we should set up a rule stating that any class that has a pubic property of type IBus should be set by our IOC container.

    SetAllProperties(y => y.OfType<IBus>());
    

    Now this on its own is not enough to inject our IBus instance into our classes as we need to call the IContainer.BuildUp() method passing in our instance of that class to inject in our IBus instance.

    This is where the following little extension method comes in handy that can be run from your application bootstrapper once StructureMap and NServiceBus have been initialized, which queries the IOC container for any pluginTypes that implement the INeedBuildUp interface foreach instance that is returned the BuildUp method is called on the container.

     public static void BuildUpThoseThatImplementINeedBuildUp(this IContainer container)
            {
                container
                    .Model
                    .PluginTypes
                    .Where(p => p.Implements<INeedBuildUp>())
                    .Select(x => x.To<INeedBuildUp>(container))
                    .Foreach(container.BuildUp);
            }
    

    Which in turn uses the following extension methods to do its magic..

    public static bool Implements<T>(this PluginTypeConfiguration configuration)
            {
                var implements = typeof (T).IsAssignableFrom(configuration.PluginType);
    
                return implements;
            }
    
     public static T To<T>(this PluginTypeConfiguration configuration, IContainer container)
            {
                return (T) container.GetInstance(configuration.PluginType);
            }
    
    public static void Foreach<T>(this IEnumerable<T&gt items, Action<T&gt action)
            {
                foreach (var item in items)
                {
                    action(item);
                }
            }
    

    Voila! you’ve now integrated StructureMap with NServiceBus in your application.

    kick it on DotNetKicks.com

    Getting Started With NServiceBus: Part 3 Sagas

    Tuesday, November 3rd, 2009

    Here are the links to the other posts in the series.

    Part 1 Unicast Messaging.
    Part 2 Publishing and Subscribing.
    Part 3 Sagas
    Part 4 Integrating With StructureMap

    Sagas are long running business processes where state needs to be shared between message handlers.

    Udi gives a much better explanation of them here and there is some more information about them on the NServiceBus Wiki here.

    Imagine the following scenario for a leave approval system.

    • An employee applies for leave.
    • The request for leave must be approved by the HR manager
    • The request for leave must be approved by the employees line Manager.
    • If both the HR manager and the line manager approve the request it can then be authorized.
    • Both the HR manager and the line manager will make their decisions independently of each other.

    The problem with this scenario is that we don’t know how long it is going to take for either the HR manager or line manager to make their decision and we don’t know in which order we are going to receive their decisions.

    NServiceBus solves these types of problems using Sagas. Lets walk through the steps we need to go through to code up this example.

    Persisting Our Saga Data

    Because a Saga is a long running transaction we will most probably want to persist some data. In our leave approval Saga example if we receive a decision from the HR Manager as to whether the request for leave has been approved or rejected for a particular employee then we will want to persist that information for later when a decision from the line manager arrives.

    Out of the box NServiceBus will allow you save the Saga data to a SQLite database using NHibernate. To define the data we wish to persist we are going to create a class called LeaveApprovalData. Because we are using NHibernate it important to make all the properties virtual if not you’ll probably get some exception like “Database was not configured through Database method.”. We also need to implement the ISagaEntity interface. You can see the the three important properties on this class are ApprovedByHR, ApprovedByLineManager and EmployeeName.

        public class LeaveApprovalData : ISagaEntity
        {
            #region Properties
    
            public virtual bool? ApprovedByHR
            {
                get; set;
            }
    
            public virtual bool? ApprovedByLineManager
            {
                get; set;
            }
    
            public virtual string EmployeeName
            {
                get; set;
            }
    
            public virtual bool HasBeenApproved
            {
                get
                {
                    var hasBeenReviewedByAll = ApprovedByHR.HasValue
                                                           && ApprovedByLineManager.HasValue;
    
                    return (hasBeenReviewedByAll
                                                         && (ApprovedByHR.Value
                                                         && ApprovedByLineManager.Value));
                }
            }
    
            public virtual bool HasBeenReviewedByAllParties
            {
                get { return ApprovedByHR.HasValue && ApprovedByLineManager.HasValue; }
            }
    
            public virtual Guid Id
            {
                get; set;
            }
    
            public virtual string OriginalMessageId
            {
                get; set;
            }
    
            public virtual string Originator
            {
                get; set;
            }
    
            #endregion Properties
        }

    Writing our Saga

    The code sample below illustrates how we could write a Saga in NServiceBus to process whether the leave request should be accepted or rejected.

        public class LeaveApprovalSaga :
                  Saga<LeaveApprovalData>,
                  ISagaStartedBy<HRLeaveApproval>,
                  ISagaStartedBy<LineManagerLeaveApproval>
    
        {
            public IBus Bus { get; set; }
    
            public override void ConfigureHowToFindSaga()
            {
                ConfigureMapping<HRLeaveApproval>(
                                     saga => saga.EmployeeName,
                                     message => message.EmployeeName);
    
                ConfigureMapping<LineManagerLeaveApproval>(
                                     saga => saga.EmployeeName,
                                     message => message.EmployeeName);
            }
    
            public void Handle(HRLeaveApproval message)
            {
                Data.EmployeeName = message.EmployeeName;
                Data.ApprovedByHR = message.Approved;
    
                Process(Data.EmployeeName);
            }
    
            private void Process(string employeeName)
            {
                if (Data.HasBeenReviewedByAllParties == false) return;
    
                if (Data.HasBeenApproved)
                {
                    LeaveApproved(employeeName);
                }
                else
                {
                    LeaveRejected(employeeName);
                }
            }
    
            public void Handle(LineManagerLeaveApproval message)
            {
                Data.EmployeeName = message.EmployeeName;
                Data.ApprovedByLineManager = message.Approved;
    
                Process(Data.EmployeeName);
            }
        }

    Lets start by looking at what the code is doing.

    The first thing to note is that we have to inherit from the generic base class Saga which is closed with our

    LeaveApprovalSaga data class.  This tells NServiceBus that we will persist an instance of the LeaveApprovalSaga for each saga.

    Starting Our Saga

    Our Saga can be started in either two ways by either a LineManagerLeaveApproval or a HRLeaveApproval message. We define this in code by implementing the following interfaces:

    ISagaStartedBy<HRLeaveApproval>, ISagaStartedBy<LineManagerLeaveApproval>

    We can receive either a LineManagerLeaveApproval or a HRLeaveApproval message in any order for a particular request which can start a new Saga.

    However we don’t always want to start a new Saga. If for example we received an HRLeaveApproval message for the employee called Tom and then an LineManagerLeaveApproval for the same employee we would not want to create a new Saga for the second message but retrieve the original one.

    So how do we tell NServiceBus to retrieve an existing Saga for a given message type? By overriding the method ConfigureHowToFindSaga and calling the method ConfigureMapping. In the example below we are stating that when we receive a HRLeaveAproval message we will look for any previously started Saga data based on our message’s  EmployeeName property. We do the same for any incoming LineManagerLeaveAproval messages to.  If either message type comes in for an employee it will start off a new saga, from then on the saga will be retrieved from the database.

            public override void ConfigureHowToFindSaga()
            {
                ConfigureMapping<HRLeaveApproval>(
                                        saga => saga.EmployeeName,
                                        message => message.EmployeeName);
    
                ConfigureMapping<LineManagerLeaveApproval>(
                                        saga => saga.EmployeeName,
                                        message => message.EmployeeName);
            }

    Handling our Messages

    Handling our messages in our Saga is very similar to implementing a normal message handler in NServiceBus when we inherit from the ISagaStartedBy<T>  interface we need to implement a Handle(T) method on our Saga.

    The main difference between a normal MessageHandler is that we want to pull out the relevant data from our incoming message and persist it in our SagaData. We can do this by accessing it through the Data property on the Saga. In the example above for the handler code for  LineManagerApproval message we firstly update our Saga with the name of the employee and then update whether or not the line manager has approved the request for leave. This is automatically persisted to our SQL Lite database.

    Configuring Your Host To Run The Saga


    1) Reference NServiceBus.dll & NServiceBus.Core.dll. I’m using StructureMap as my IOC container so I have also referenced the NServiceBus.ObjectBuilder.StructureMap.dll as well.
    2)
    In your Bootstrapper you need to configure NServiceBus.

    Configure
                    .With()
                    .StructureMapBuilder(container)
                    .XmlSerializer()
                    .MsmqTransport()
                    .IsTransactional(true)
                    .PurgeOnStartup(false)
                    .UnicastBus()
                    .LoadMessageHandlers()
                    .ImpersonateSender(false)
                    .Sagas()
                    .NHibernateSagaPersisterWithSQLiteAndAutomaticSchemaGeneration()
                    .CreateBus()
                    .Start();
    

    3) In the Application Config add the following

    
    

    4) Now define the Host’s Input Queue and the Error Queue – where undelivered messages are put if there is an exception delivering the message in the config file

    
    

    That’s it you’ve implemented your first Saga in NServiceBus!

    kick it on DotNetKicks.com

    Getting Started With NServiceBus: Part 2 Publishing And Subscribing

    Wednesday, October 28th, 2009

    This post details the steps that you need to take to configure a self hosted publisher and subscriber. With the Publisher Subscriber model in NService Bus multiple clients (subscribers) can subscribe to particular messages from a publisher. The Publisher will manage the subscriptions and Publish any messages to the Bus which will be distributed to all the subscribers.

    Part 1 Unicast Messaging.
    Part 2 Publishing and Subscribing.
    Part 3 Sagas
    Part 4 Integrating With StructureMap

    Configuring The Subscriber

    1) Reference NServiceBus.dll & NServiceBus.Core.dll. I’m using StructureMap as my IOC container so I have also referenced the NServiceBus.ObjectBuilder.StructureMap.dll as well.
    2) In your Bootstrapper you need to configure NServiceBus

                 Configure
                  .With()
                  .StructureMapBuilder()
                  .XmlSerializer()
                  .MsmqTransport()
                  .IsTransactional(true)
                  .PurgeOnStartup(false)
                  .UnicastBus()
                  .ImpersonateSender(false)
                  .LoadMessageHandlers()
                  .CreateBus()
                  .Start();
    

    3) In the Application Config add the following

    
    

    4) Now define the Subscribers’ Input Queue (where the subscribed to messages are sent to) and the Error Queue – where undelivered messages are put if there is an exception delivering the message in the config file

    
    

    5) Now define the endpoint of the publisher that you wish to subscribe to messages from. This is a mapping between a message type and a particular publisher. You can either subscribe to all messages from an assembly or specify the type explicitly. In the example below I have specified that we wish to subscribe to every message in the Messages.dll that might be published.

    
        
          
        
      
    

    Configuring The Publisher

    6) Repeat steps 1) & 3) for the Server
    7) Configure NServiceBus to run as a Publisher

                Configure
                 .With()
                 .StructureMapBuilder()
                 .MsmqSubscriptionStorage()
                 .XmlSerializer()
                 .MsmqTransport()
                 .IsTransactional(true)
                 .PurgeOnStartup(false)
                 .UnicastBus()
                 .ImpersonateSender(false)
                 .CreateBus()
                 .Start();
    

    8 ) Now define the Publishers’ Input Queue (where subscription requests are sent to) and the Error Queue – where undelivered messages are put if there is an exception delivering the message in the config file

      
    

    9) When you run up the applications NServiceBus will create the relevant queues for you. But be careful make sure you start up the Publisher first otherwise the subscriber will throw an exception as there is no queue for it to put a subscription on.

    The important thing to note with the Publisher is that we have configured it with the use MsmqSubscriptionStorage() line. NServiceBus will create an additional queue called nservicebus_subscriptions and will store each subscription as an individual message on that queue. It is possible to use NHibernate to manage your subscriptions in a database if that is required.

    Pubishing a Message

    Simply call the Publish method on the instance of you Bus

    eg.

    Bus.Publish(new Message());

    or

    Bus.Publish();

    The documentation at the NServiceBus web site has more detailed information on this.

    kick it on DotNetKicks.com

    Getting Started With NServiceBus: Part 1 Unicast Messaging

    Tuesday, October 27th, 2009

    I’ve been doing a bit of work with NServiceBus recently on a project and found it to be a really powerful and robust tool once you get it working. However like most open source projects and Udi will admit this himself the documentation is somewhat lacking.

    I haven’t done anything too complicated with NServiceBus and these are more notes for myself rather than anything else but I thought i’d put up a series of posts on some of the basic scenarios.

    Part 1 Unicast Messaging.
    Part 2 Publishing and Subscribing.
    Part 3 Sagas
    Part 4 Integrating With StructureMap

    Configuring The Client

    This is your basic point to point messaging and is very similar to your typical wcf client calling a wcf service. This example show how to get NServiceBus working in your own application rather than using the self host.

    1) Reference NServiceBus.dll & NServiceBus.Core.dll
    2) In your Bootstrapper you need to configure NServiceBus

     Configure.With()
                    .SpringBuilder()
                    .XmlSerializer()
                    .MsmqTransport()
                    .IsTransactional(true)
                    .PurgeOnStartup(false)
                    .UnicastBus()
                    .ImpersonateSender(false)
                    .CreateBus()
                    .Start();
    

    3) In the Application Config add the following

    
    

    4) Now define the Client’s Input Queue (where response messages are sent to) and the Error Queue – where undelivered messages are put if there is an exception delivering the message in the config file

    
    

    5) Now define the endpoint you wish to send the messages to this is essentially a mapping between a message type and an endpoint queue. You can either send all messages from an assembly to a particular
    endpoint queue or you can specify a specific type. In the example below I have specified that every message in the Messages.dll should be sent to the Server_Input queue.

    
        
          
        
      
    

    Configuring The Server

    6) Repeat steps 1) & 3) for the Server
    7) Configure NServiceBus to run as a server the important difference between this and the client is the
    LoadMessageHandlers() line which means we will handle the incoming messages.

    
         Configure
                    .With()
                    .SpringBuilder()
                    .XmlSerializer()
                    .MsmqTransport()
                    .IsTransactional(true)
                    .PurgeOnStartup(false)
                    .UnicastBus()
                    .ImpersonateSender(false)
                    .LoadMessageHandlers()
                    .CreateBus()
                    .Start();
    

    8 ) Now define the Server’s Input Queue (where request messages are sent to) and the Error Queue – where undelivered messages are put if there is an exception delivering the message in the config file

    
    

    9) That’s it! when you run up the applications NServiceBus will create all the queues automatically for you (you can specify it not to do this if you wish)