NServiceBus Host

Project Hosting | Nuget: NServiceBus.Host (Version: 7.x)
Target NServiceBus Version: 6.x

The NServiceBus Host takes a more opinionated approach to hosting. It allows the execution as both a windows service and a console application (for development).

To use the host create a new C# class library and reference the NServiceBus.Host NuGet package. The package also creates an example endpoint configuration and sets the NServiceBus.Host.exe as the startup project for the endpoint.

Configuring the endpoint

The NServiceBus.Host.exe scans the runtime directory for assemblies containing a class that implements the IConfigureThisEndpoint interface. This class will contain the configuration for this endpoint. Read more on how NServiceBus does assembly scanning.

To avoid the scanning process, configure the type of the endpoint configuration by adding the following to the NServiceBus.Host.exe.config file. The below example show the exact syntax:

<configuration>
  <appSettings>
    <add key="EndpointConfigurationType"
         value="YourNamespace.YourTypeName, YourAssembly"/>
  </appSettings>
</configuration>

Controlling assembly scanning using code

By default, the assembly scanning process of the host is equal to a regular endpoint. It can be configured by the the assembly scanning API via IConfigureThisEndpoint:

public class EndpointConfig :
    IConfigureThisEndpoint
{
    public void Customize(EndpointConfiguration endpointConfiguration)
    {
        // use 'endpointConfiguration' object to configure scanning
    }
}

Controlling assembly scanning using the command line

A list of assemblies to scan can also be controlled using the /scannedAssemblies switch. If this option is used, the NServiceBus.Host.exe loads only assemblies that have been explicitly listed on the command line. Each assembly must be added using a separate switch:

NServiceBus.Host.exe /scannedAssemblies:"NServiceBus.Host" /scannedAssemblies:"MyMessages" /scannedAssemblies:"MyEndpoint"

The host loads the assemblies by invoking Assembly.Load method. This approach ensures that the specified assembly and all its dependent assemblies will also be loaded.

It is mandatory to include NServiceBus.Host in the /scannedAssemblies list as shown in the example above. As NServiceBus.Host references NServiceBus.Core, the latter can be safely omitted from the list.

Application Domains

The NServiceBus.Host.exe creates a separate service Application Domain to run NServiceBus and the user code. The new domain is assigned a configuration file named after the dll that contains the class implementing IConfigureThisEndpoint. All the configuration should be done in that file (as opposed to NServiceBus.Host.exe.config). In most cases that means just adding the app.config file to the project and letting MSBuild take care of renaming it while moving to the bin directory.

When the endpoint configuration is not specified explicitly, the host scans all the assemblies to find it and it does so in the context of the host application domain, not the new service domain. Because of that, when redirecting assembly versions, the assemblyBinding element needs to be present in both NServiceBus.Host.exe.config and app.config.

Custom initialization

For Versions 5 and above, customize the endpoint behavior using the IConfigureThisEndpoint.Customize method on the endpoint configuration class. Call the appropriate methods on the parameter passed to the method.

class CustomizingHost :
    IConfigureThisEndpoint
{
    public void Customize(EndpointConfiguration endpointConfiguration)
    {
        // To customize, use the configuration parameter.
        endpointConfiguration.UseSerialization<JsonSerializer>();
        endpointConfiguration.UsePersistence<InMemoryPersistence>();
    }
}

Roles - Built-in configurations

Specify Endpoint Name

Namespace convention

When using NServiceBus.Host, the namespace of the class implementing IConfigureThisEndpoint will be used as the endpoint name as the default convention. In the following example the endpoint name when running NServiceBus.Host.exe becomes MyServer. This is the recommended way to name a endpoint. Also this emphasizes convention over configuration approach.

namespace MyServer
{
    using NServiceBus;

    public class EndpointConfigByNamespace :
        IConfigureThisEndpoint,
        AsA_Server
    {
        // ... custom config

Defined in code

Set the endpoint name using the DefineEndpointName(name) extension method on the endpoint configuration.

public void Customize(EndpointConfiguration endpointConfiguration)
{
    endpointConfiguration.DefineEndpointName("CustomEndpointName");
}

EndpointName attribute

Set the endpoint name using the [EndpointName] attribute on the endpoint configuration.

This will only work when using NServiceBus host.
[EndpointName("MyEndpointName")]
public class EndpointConfigWithAttribute :
    IConfigureThisEndpoint, AsA_Server
{
    // ... custom config

Default Critical error action handling

The default Critical Error Action for the Host is:

if (Environment.UserInteractive)
{
    // so that user can see on their screen the problem
    Thread.Sleep(10000);
}

string fatalMessage = $"NServiceBus critical error:\n{errorMessage}\nShutting down.";
Environment.FailFast(fatalMessage, exception);
It is important to consider the effect these defaults will have on other things hosted in the same process. For example if co-hosting NServiceBus with a web-service or website.

Performance Counters

SLA violation countdown

In the NServiceBus Host this counter is enabled by default. But the value can be configured either by the above API or using a EndpointSLAAttribute on the instance of IConfigureThisEndpoint.

[EndpointSLA("00:03:00")]
public class EndpointConfig :
    IConfigureThisEndpoint
{

When Endpoint Instance Starts and Stops

public class Bootstrapper :
    IWantToRunWhenEndpointStartsAndStops
{
    public Task Start(IMessageSession session)
    {
        // Do startup actions here.
        // Either mark Start method as async or do the following
        return Task.CompletedTask;
    }

    public Task Stop(IMessageSession session)
    {
        // Do cleanup actions here.
        // Either mark Stop method as async or do the following
        return Task.CompletedTask;
    }
}

Samples

Related Articles


Last modified