Solutions    |    Downloads    |    License    |    Documentation    |    Training    |    Support    |    Customers    |    About Us

Unobtrusive Sample

Last Updated: Dec 18, 2012 07:03PM IST

In order to demonstrate NServiceBus operating in unobtrusive mode open the unobtrusive sample.

First of all run the solution - you should see two console applications start up. Find the client application by looking for the one with "Client" in its path and follow the onscreen instructions to send some messages to the server.

Configuring Unobtrusive message

Below is a snippet that shows how to pass in your own conventions to determine which types are message definitions instead of using the IMessage, ICommand or IEvent interfaces:

Configure.With()
     .DefaultBuilder()
     .FileShareDataBus(@"\\MyDataBusShare\")
     .DefiningCommandsAs(t => t.Namespace != null && t.Namespace.EndsWith("Commands"))
     .DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"))
     .DefiningMessagesAs(t => t.Namespace == "Messages")
     .DefiningEncryptedPropertiesAs(p => p.Name.StartsWith("Encrypted"))
     .DefiningDataBusPropertiesAs(p => p.Name.EndsWith("DataBus"))
     .DefiningExpressMessagesAs(t => t.Name.EndsWith("Express"))
     .DefiningTimeToBeReceivedAs(t => t.Name.EndsWith("Expires") 
          ? TimeSpan.FromSeconds(30) 
          : TimeSpan.MaxValue);

The code above tells NServiceBus to treat all types with a namespace that ends with "Messages" the same as to messages that explicitly implement IMessage.
As you see you can also specify conventions for the new ICommand and IEvent feature.

NServiceBus supports property level encryption by using a special WireEncryptedString property and the snippet above shows the unobtrusive way to tell NServiceBus which properties you want to be encrypted.

The snippet above also shows the unobtrusive way to tell NServiceBus which properties will be delivered on a separate channel from the message itself using the Data Bus feature, and which messages are express or/and have a time to be received.

Now let's go look at the code:

There are a number of projects in the solution:

  1. Client Class library for sending a request and a command to the server and handle a published event
  2. Server Class library for handling requests and commands and publish events
For the next three projects of message definitions, please open the references to see that no references are required for NServiceBus libraries. No reference enables decoupling between those projects to NServiceBus versioning.
  1. Commands Class library for defining command and definition for a returned status.
  2. Events Class library for defining an event.
  3. Messages Class library for defining a request and a response message. This project also includes messages that are express and have a time to be received.

Sample messaging patterns

This sample contains three messaging patterns:
  1. Full Duplex Also known as Send/Reply, In this messaging pattern the client will Send a Request and handle a Response that was Replied by the server.
  2. Command In this messaging pattern the client will send a Command to the server that will Return a status.
  3. Messages Class library for defining a request and a response message. Please open the references to see that no references are required for NServiceBus libraries.

Send/Reply messaging pattern code

For full sample please visit the Full Duplex sample.

Client side

Message declaration

The following code, at the client project endpointConfig does the messages configuration:

.DefiningCommandsAs(t => t.Namespace != null && t.Namespace.EndsWith("Commands"))
     .DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"))
     .DefiningMessagesAs(t => t.Namespace == "Messages")
The above lines of code tells NServiceBus that it should treat classes that are declared in the Messages namespace as if they were explicitly implementing the IMessage interface. Any type in a namespace ending with "Events" should be treated as if they were explicitly implementing the IEvent and finally any type in a namespace ending with "Commands" should be treated as if they were explicitly implementing the ICommand.

Let's open the client application configuration file (app.config) to see its configuration:

<add Messages="Messages" Endpoint="server"/>
The above declaration instruct NServiceBus that the target of IMessage type messages is the Server endpoint. 

The following is the client code to send the Request:

Bus.Send<Request>(m =>
{
    m.RequestId = requestId;
});

Server side

At the server side, it is handling the Request in the RequestMessageHandler class and only Replying back to the client as follows:

Bus.Reply(new Response
{
    ResponseId = message.RequestId
});

Back to the client code we will find a Response handler code:

public class ResponseHandler : IHandleMessages<Response>

Command/Status messaging pattern code

Client side

Message declaration

The following declaration instructs NServiceBus to use those classes with namespace that ends with Commands the same as to messages that are explicitly implements the ICommand interface

.DefiningCommandsAs(t => t.Namespace != null && t.Namespace.EndsWith("Commands"))

Let's open the client application configuration file (app.config) to see its configuration:

<add Messages="Commands" Endpoint="server"/>

The above declaration instruct NServiceBus that the target of ICommand type messages is the Server endpoint.

The following is the client code to send the Command:
Bus.Send<MyCommand>(m =>
{
    m.CommandId = commandId;
    m.EncryptedString = "Some sensitive information";
}).Register<CommandStatus>(outcome=> Console.WriteLine("Server returned status: " + outcome));

The client is sending a message and registering a method to handle returned status.

Server side

At the server side, it is handling in the Handle method, and all it is doing is sending back an OK status:

public class MyCommandHandler : IHandleMessages<MyCommand>
{
    readonly IBus bus;

    public MyCommandHandler(IBus bus)
    {
        this.bus = bus;
    }

    public void Handle(MyCommand message)
    {
        Console.WriteLine("Command received, id:" + message.CommandId);
        Console.WriteLine("EncryptedString:" + message.EncryptedString);

        bus.Return(CommandStatus.Ok);
    }
}

The message.EncryptedString is encrypted by the NServiceBus framework since it was declared as follows, in the endpointConfig class (of both client and server):

Configure.With()
     .DefaultBuilder()
     .FileShareDataBus(@"\\MyDataBusShare\")
     .DefiningCommandsAs(t => t.Namespace != null && t.Namespace.EndsWith("Commands"))
     .DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"))
     .DefiningMessagesAs(t => t.Namespace == "Messages")
     .DefiningEncryptedPropertiesAs(p => p.Name.StartsWith("Encrypted"))
     .DefiningDataBusPropertiesAs(p => p.Name.EndsWith("DataBus"))
     .DefiningExpressMessagesAs(t => t.Name.EndsWith("Express"))
     .DefiningTimeToBeReceivedAs(t => t.Name.EndsWith("Expires") 
          ? TimeSpan.FromSeconds(30) 
          : TimeSpan.MaxValue);

The above code instructs NServiceBus to encrypt any property that starts with the string Encrypted and resides in any class in the namespaces that ends with Command or Events, or at namespaces that equal to Messages.
The encryption algorithm is declared at App.config of both client and server with the RijndaelEncryptionServiceConfig section name. Please see the Encryption sample for more details.

Publish/Subscribe messaging pattern code

For full sample please visit the PubSub documentation

Client side

Message declaration

The following declaration instructs NServiceBus to use those classes with namespace that ends with Events the same as to messages that are explicitly implements the IEvent interface

.DefiningEventsAs(t => t.Namespace != null && t.Namespace.EndsWith("Events"))

Let's open the client application configuration file (app.config) to see its configuration:

<add Messages="Events" Endpoint="server"/>

The above declaration instruct NServiceBus that the target of IEvent type messages is the Server endpoint. In the case of events, it means that the client subscribe to the publishing Server endpoint.

The following is the client code to handle published events and just print a message to the console:
public class MyEventHandler : IHandleMessages<IMyEvent>
{
    public void Handle(IMyEvent message)
    {
        Console.WriteLine("IMyEvent received from server with id:" + message.EventId);
    }
}

Server side

At the server side, it is publishing an event as follows:

Bus.Publish<IMyEvent>(m =>
{
    m.EventId = eventId;
});

When using naming convention to mark your commands events and messages, you can achieve freedom from dependency on NServiceBus message versioning.
As can be seen from this sample, after declaring messages, commands and events, NServiceBus sending and receiving code is identical to a scenarios where the messages interface implementation is done explicitly.

Where to go next?

It might be a good idea now to cover the Message Mutators subject, here.

About NServiceBus    |    Contact Us    |    Privacy    |    Follow us on:   
Copyright 2010-2013 NServiceBus. All rights reserved
support@nservicebus.com
http://assets3.desk.com/raca8b478c9bd89640c451013350d59caa6b66ee1/javascripts/
nservicebus
Loading
seconds ago
a minute ago
minutes ago
an hour ago
hours ago
a day ago
days ago
about
true
Invalid characters found
/customer/en/portal/articles/autocomplete
There was an error contacting Get Satisfaction
View All
0
discussions
replies
Questions
Ideas
Problems
Praise