5 Comments

Getting the NServiceBus 2.0 to work with .NET Framework 4 can be little problematic. Here’s a short tutorial on how to get the server side up and running.

1. Downloading and compiling the source

First, get the latest NServiceBus source code from the github. Patch was added to the source in April 13, 2010, which allows NServiceBus to work with the latest framework. After downloading the source, use the build-ne4.bat to compile the project.

2. Creating the project

Now start up your Visual Studio 2010 and create a new Class Library project. Add the references to these files (use the dlls you compiled in the first phase):

  • log4net.dll
  • NServiceBus.Core.dll
  • NServiceBus.dll
  • System.Data.SQLite.dll (make sure to use the one from x64 folder if you have x64 Windows)

Now open up the automatically generated Class1.cs and decorate it with two different NServiceBus interfaces:

<span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">using</span> NServiceBus;

<span style="color: #606060" id="lnum2">   2:</span>  

<span style="color: #606060" id="lnum3">   3:</span> <span style="color: #0000ff">namespace</span> ClassLibrary1

<span style="color: #606060" id="lnum4">   4:</span> {

<span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Class1 : IConfigureThisEndpoint, AsA_Server

<span style="color: #606060" id="lnum6">   6:</span>     {

<span style="color: #606060" id="lnum7">   7:</span>  

<span style="color: #606060" id="lnum8">   8:</span>     }

<span style="color: #606060" id="lnum9">   9:</span> }

Build your solution at this point. Then open the project’s properties and make the project start an external program NServiceBus.Host.exe when debugging. Make sure you point to the exe file in your bindebug-folder:

external

3. Adding the configuration file

We need a configuration file to get things working. Add app.config to the project and fill in the NServiceBus-related sections. Your configuration should look like this:

&lt;?xml version=<span style="color: #006080">&quot;1.0&quot;</span> encoding=<span style="color: #006080">&quot;utf-8&quot;</span> ?&gt;

<configuration>

 

  <configSections>

    &lt;section name=<span style="color: #006080">&quot;MsmqTransportConfig&quot;</span> type=<span style="color: #006080">&quot;NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core&quot;</span> /&gt;

    &lt;section name=<span style="color: #006080">&quot;UnicastBusConfig&quot;</span> type=<span style="color: #006080">&quot;NServiceBus.Config.UnicastBusConfig, NServiceBus.Core&quot;</span> /&gt;

  </configSections>

 

  <MsmqTransportConfig

  InputQueue=<span style="color: #006080">&quot;InputQueue&quot;</span>

  ErrorQueue=<span style="color: #006080">&quot;error&quot;</span>

  NumberOfWorkerThreads=<span style="color: #006080">&quot;1&quot;</span>

  MaxRetries=<span style="color: #006080">&quot;5&quot;</span>

  />

 

  <UnicastBusConfig

    DistributorControlAddress=<span style="color: #006080">&quot;&quot;</span>

    DistributorDataAddress=<span style="color: #006080">&quot;&quot;</span>&gt;

    <MessageEndpointMappings>

    </MessageEndpointMappings>

  </UnicastBusConfig>

 

</configuration>

You’re ready to start your server! Hit F5 and you should see a console window to pop out.  Too bad that the program will crash almost immediately with the following exception:

Exception when starting endpoint, error has been logged. Reason: Could not load file or assembly 'file:///C:devspikesClassLibrary1ClassLibrary1binDebuglog4net.dll' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)

If we would have used the .NET Framework 3.5, everything would have gone nice and smooth.

4. Adding the .NET Framework 4.0 compatibility sugar

So, what went wrong? If you use the command line and start your server from there, you will get more detailed descriptions. Here’s an interesting part from the exception:

System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does  not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.

This is one of the small things which have changed between the .NET Framework 3.5 and 4.0. If you follow the link provided by the exception, you will find a detailed description on what has changed between the frameworks. As you can see from the exception, the new framework is treating the log4net.dll as it was run from a network location. This is because the file “is flagged by Windows as being a Web application, even if it resides on the local computer.”

To fix the problem, add a new configuration file to your program and name it “NServiceBus.Host.exe.config”. Before editing the file, make sure to tick the “Copy to output directory” property of the file to “Copy always”. We’re going to use the information acquired from the exception details to add the correct configuration:

&lt;?xml version=<span style="color: #006080">&quot;1.0&quot;</span> encoding=<span style="color: #006080">&quot;utf-8&quot;</span> ?&gt;

<configuration>

  <runtime>

    &lt;loadFromRemoteSources enabled=<span style="color: #006080">&quot;true&quot;</span>/&gt;

  </runtime>

</configuration>

And that’s it! After compiling your project you should have two configuration files in the  debug-directory:

  • ClassLibrary1.dll.config
  • NServiceBus.Host.exe.config

Now just run the exe or press F5 in Visual Studio and you should see the familiar NServiceBus debug output.

9 Comments

If you’re trying to use the NServiceBus.Host.exe in a x64 system, you may encounter the following exception:

Unhandled Exception: System.InvalidOperationException: No endpoint configuration found in scanned assemblies. This usually happens when NServiceBus fails to load your assembly contaning IConfigureThisEndpoint. Try specifying the type explicitly in the NServiceBus.Host.exe.config using the appsetting key: EndpointConfig...

To fix this, make sure that all your projects target the same platform (x64 / x86) as your NServiceBus.Host.exe.

In my case the server dll and the messages dll were build with the x86 switch and the NServiceBus.Host.exe was built with “any cpu”. This combination threw an exception as soon as I started the exe-file. Creating a configuration file for the host and defining the EndPointConfigurationType in it didn’t help. Changing the server dll to be build with “any cpu” didn’t help. But changing both the server dll and the messages dll to use the “any cpu” switch immediately fixed the problem.

0 Comments

NServiceBus uses log4net for its logging purposes. If you’ve run one the samples which are included with the NServiceBus package, you could be overwhelmed of all the logging that the NServiceBus.Host.exe prints to the console windows. If you’re just starting your journey with the NServiceBus, all the logging may make it hard to understand the samples, because there’s so much text. But, fortunately, it’s really easy to change the sample projects so that the Log4Net configuration is read from a configuration file. This way you can easily change how much log information is shown on the console windows.

The tutorial works with NServiceBus 2.0 RTM.


1. Modifying the source code

 

We’re going to change one of the NServiceBus samples so that a user can adjust the log4net logging through the configuration file.
Start by opening the FullDuplex-sample solution (located in nservicebus/samples/FullDuplex) –folder. You should see four projects:

  • MyClient
  • MyMessages
  • MyServer
  • MyServer.Tests

We’re going to change MyServer but this tutorial can be applied to the MyClient also. Open the MyServerEndpointConfig.cs and you should see this:

   1: public class ServerInit : IWantCustomInitialization
   2: {
   3:     public void Init()
   4:     {
   5:         Configure.Instance.RijndaelEncryptionService();
   6:     }
   7: }

We’re going to change two things. First, make the ServerInit-class to implement IWantCustomLogging. Then, add the following line in the Init-method:

NServiceBus.SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);

So you should end up with a class like this:

   1: public class ServerInit : IWantCustomInitialization, IWantCustomLogging
   2: {
   3:     public void Init()
   4:     {
   5:         Configure.Instance.RijndaelEncryptionService();
   6:         NServiceBus.SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);
   7:     }
   8: }
If you now build the project and run it, you should see an error in the console output:

log4net:ERROR XmlConfigurator: Failed to find configuration section 'log4net'…

Lets fix this next.

2. Modifying the configuration file

We’re going to add a standard log4net section to the configuration file. This way you don’t have to recompile the project any more if you want to change how much log is shown in the console window.

First, locate the MyServer.dll.config –file. Then, in the configSections , add a new section for the log4net:

   1: <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>

Then add the log4net configuration outside the configSections. Here’s a sample configuration which shows only INFO-messages (and higher) on the console:

   1: <log4net debug="false">
   2:   <appender name="console" type="log4net.Appender.ConsoleAppender">
   3:     <layout type="log4net.Layout.PatternLayout">
   4:       <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n"/>
   5:     </layout>
   6:   </appender>
   7:   <root>
   8:     <level value="INFO"/>
   9:     <appender-ref ref="console"/>
  10:   </root>
  11: </log4net>
Save the configuration file and start the NServiceBus.Host.Exe. You should see much less log information.

Conclusion

It’s only a matter of two code changes to get the full control for your logging needs by making the NServiceBus.Host.exe to read the log4net configuration from the application’s configuration file.

Links

2 Comments

NServiceBus 2.0 RTM doesn’t contain a sample of how to use one of its nicest features: the distributor. By reading this blog post you will learn how to modify the FullDuplex-sample so that it uses the distributor model.

Background

NserviceBus’ documentation contains a good article about the logic behind the distributor. Here’s one part from the documentation which nicely sums it up:

You can think of the distributor as something like a load balancer - it distributes the messages coming to it to a number of other machines. This kind of physical one-to-many communication is needed for scaling out the number of machines running for a given subscriber, but doesn't actually entail any pub/sub. Each subscriber gets its own distributor and each of them decides independently to which machine it will pass its mesdistributorsages.

Here’s a small picture to light things up. As you can see, when using the distributor, the client doesn’t talk directly with the server but instead it communicates with the distributor. Distributor then forwards the received message to one of its workers. All workers can be located on the same server or every worker can have a dedicated server.

Aim of this post

We’re going to modify the FullDuplex-sample, which is included with the NServiceBus package, to use the distributor. In the end we’re going to have one client, one distributor and two workers all communicating with each other. And before we proceed, here’s a spoiler: We only need to touch the configuration files.

1. Configuring the distributor

You can locate the NServiceBus distributor from Nservicebusprocessesdistributor. Open the configuration file NServiceBus.Distributor.dll.config and then… you can close it. There’s nothing in there which we need to change! You can immediately start the NServiceBus distributor by starting the NServiceBus.Host.exe. Make sure you don’t see any error messages.

2. Configuring the client

Next, open the FullDuple-sample and then locate the MyClient-project and the contained configuration file App.config. In this step we actually have to modify the configuration file but it’s a simple change. By default the UnicastBusConfig looks like this:

<span style="color: #606060" id="lnum1">   1:</span> &lt;UnicastBusConfig&gt;

<span style="color: #606060" id="lnum2">   2:</span>   &lt;MessageEndpointMappings&gt;

<span style="color: #606060" id="lnum3">   3:</span>     &lt;add Messages=<span style="color: #006080">&quot;MyMessages&quot;</span> Endpoint=<span style="color: #006080">&quot;MyServerInputQueue&quot;</span> /&gt;

<span style="color: #606060" id="lnum4">   4:</span>   &lt;/MessageEndpointMappings&gt;

<span style="color: #606060" id="lnum5">   5:</span> &lt;/UnicastBusConfig&gt;

But like we’ve have learned, the client shouldn’t try to send the messages to the server (worker) but to the distributor. And to be specific, the messages should go to the distributor’s DataInputQueue. Because we didn’t change anything in the distributor’s default configuration file, the client should send the messages to a queue named distributorDataBus. So let’s make the change:

<span style="color: #606060" id="lnum1">   1:</span> &lt;UnicastBusConfig&gt;

<span style="color: #606060" id="lnum2">   2:</span>   &lt;MessageEndpointMappings&gt;

<span style="color: #606060" id="lnum3">   3:</span>     &lt;add Messages=<span style="color: #006080">&quot;MyMessages&quot;</span> Endpoint=<span style="color: #006080">&quot;distributorDataBus&quot;</span> /&gt;

<span style="color: #606060" id="lnum4">   4:</span>   &lt;/MessageEndpointMappings&gt;

<span style="color: #606060" id="lnum5">   5:</span> &lt;/UnicastBusConfig&gt;

Now you can start the client. Wait for it to initialize and then use enter to send a message. You should see some activity on the distributor. But we’re still missing our workers so the client isn’t getting the replies it is waiting for.

3. Configuring the worker

We must change the worker’s configuration so that it can make itself available to the distributor. And again, the changes are small. First, give the worker a dedicated queue by changing the InputQueue to “worker”. Your MsmqTransportConfig-section should now look like this:

<span style="color: #606060" id="lnum1">   1:</span> &lt;MsmqTransportConfig

<span style="color: #606060" id="lnum2">   2:</span>   InputQueue=<span style="color: #006080">&quot;worker&quot;</span> 

<span style="color: #606060" id="lnum3">   3:</span>   ErrorQueue=<span style="color: #006080">&quot;error&quot;</span>

<span style="color: #606060" id="lnum4">   4:</span>   NumberOfWorkerThreads=<span style="color: #006080">&quot;1&quot;</span>

<span style="color: #606060" id="lnum5">   5:</span>   MaxRetries=<span style="color: #006080">&quot;5&quot;</span>

<span style="color: #606060" id="lnum6">   6:</span> /&gt;

Then, in the UnicastBusConfig-section, type in the DistributorControlAddress and the DistributorDataAddress. You can find the correct values from the distributor’s configuration. Because we’re using the default configuration, the worker’s configuration should end up looking this:

<span style="color: #606060" id="lnum1">   1:</span> &lt;UnicastBusConfig

<span style="color: #606060" id="lnum2">   2:</span>   DistributorControlAddress=<span style="color: #006080">&quot;distributorControlBus&quot;</span>

<span style="color: #606060" id="lnum3">   3:</span>   DistributorDataAddress=<span style="color: #006080">&quot;distributorDataBus&quot;</span>&gt;

<span style="color: #606060" id="lnum4">   4:</span>   &lt;MessageEndpointMappings /&gt;

<span style="color: #606060" id="lnum5">   5:</span> &lt;/UnicastBusConfig&gt;

And that’s it. You can now start the server and after the initialization, the client should receive its reply. Keep pressing enter in the client console and you should see messages flying around.

4. Creating an another workerworker2

We’re almost there. The aim was to have two workers so we’re going to do just that. Here’s how to do this:

  1. Create a copy of the worker’s bin-folder (see picture).
  2. Open the configuration file from the newly copied folder.
  3. Change the InputQueue to “worker2”.
  4. Start the worker.

Now when you again start hitting the enter-key in the client console you should see NServiceBus distributor in action: messages are handled by both of the workers. Here’s a picture from my screen after I had hit the enter for twenty times: capture

Conclusion

Modifying the default FullDuplex sample to use the NServiceBus distributor required only some small changes to the configuration files. In future posts, I’m hoping to expand on the topics related to the NServiceBus configuration: in this post we just skimmed through the changes to get things running.

Links: