Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Upgrade Version 6 to 7

Component: NServiceBus

Upgrading a major dependency like NServiceBus requires careful planning, see the general recommendations article to learn more about the optimal upgrade process.

Configuration

The configuration APIs IProvideConfiguration, IConfigurationSource, and CustomConfigurationSource have been deprecated. The equivalent code-based API are shown in the remainder of this section.

Auditing

Configuring auditing via the following APIs has been deprecated:

  • IProvideConfiguration<AuditConfig>
  • AuditConfig in an app.config configSections
  • Returning an AuditConfig from an IConfigurationSource
  • HKEY_LOCAL_MACHINE\SOFTWARE\ParticularSoftware\ServiceBus\AuditQueue registry key

Instead use one of the following methods:

Configure with the code API

endpointConfiguration.AuditProcessedMessagesTo(
    auditQueue: "targetAuditQueue",
    timeToBeReceived: TimeSpan.FromMinutes(10));

Read from appSettings and configure with the code API

<configuration>
  <appSettings>
    <add key="AuditQueue"
         value="targetAuditQueue" />
    <add key="TimeToBeReceived"
         value="00:10:00" />
  </appSettings>
</configuration>
var appSettings = ConfigurationManager.AppSettings;
var auditQueue = appSettings.Get("auditQueue");
var timeToBeReceivedSetting = appSettings.Get("timeToBeReceived");
var timeToBeReceived = TimeSpan.Parse(timeToBeReceivedSetting);
endpointConfiguration.AuditProcessedMessagesTo(
    auditQueue: auditQueue,
    timeToBeReceived: timeToBeReceived);

Logging

Configuring logging via the following APIs has been deprecated:

  • IProvideConfiguration<Logging>
  • Logging in an app.config configSections

Instead use one of the following methods:

Configure with the code API

var logFactory = LogManager.Use<DefaultFactory>();
logFactory.Level(LogLevel.Info);

Read from appSettings and configure with the code API

<appSettings>
  <add key="LoggingThreshold"
       value="Debug" />
</appSettings>
var appSettings = ConfigurationManager.AppSettings;
var appSetting = appSettings.Get("LoggingThreshold");
var level = (LogLevel)Enum.Parse(typeof(LogLevel), appSetting);
var logFactory = LogManager.Use<DefaultFactory>();
logFactory.Level(level);

Error queue

Configuring the error queue via the following APIs has been deprecated:

  • IProvideConfiguration<MessageForwardingInCaseOfFaultConfig>
  • MessageForwardingInCaseOfFaultConfig in an app.config configSections
  • Returning a MessageForwardingInCaseOfFaultConfig from an IConfigurationSource
  • HKEY_LOCAL_MACHINE\SOFTWARE\ParticularSoftware\ServiceBus\ErrorQueue registry key

Instead use one of the following methods:

Configure with the code API

endpointConfiguration.SendFailedMessagesTo("error");

Read from appSettings and configure with the code API

<configuration>
  <appSettings>
    <add key="ErrorQueue"
         value="error" />
  </appSettings>
</configuration>
var appSettings = ConfigurationManager.AppSettings;
var errorQueue = appSettings.Get("errorQueue");
endpointConfiguration.SendFailedMessagesTo(errorQueue);

Endpoint mappings

Configuring endpoint mappings via the following APIs has been deprecated:

  • IProvideConfiguration<UnicastBusConfig>
  • UnicastBusConfig/MessageEndpointMappings in an app.config configSections
  • Returning a UnicastBusConfig from an IConfigurationSource

It can be replaced with a combination of the following methods:

Command routing

var transport = endpointConfiguration.UseTransport<MyTransport>();

var routing = transport.Routing();
routing.RouteToEndpoint(
    assembly: typeof(AcceptOrder).Assembly,
    destination: "Sales");

routing.RouteToEndpoint(
    assembly: typeof(AcceptOrder).Assembly,
    @namespace: "PriorityMessages",
    destination: "Preferred");

routing.RouteToEndpoint(
    messageType: typeof(SendOrder),
    destination: "Sending");

Event routing

var transport = endpointConfiguration.UseTransport<MyTransport>();

var routing = transport.Routing();
routing.RegisterPublisher(
    assembly: typeof(OrderAccepted).Assembly,
    publisherEndpoint: "Sales");

routing.RegisterPublisher(
    assembly: typeof(OrderAccepted).Assembly,
    @namespace: "PriorityMessages",
    publisherEndpoint: "Preferred");

routing.RegisterPublisher(
    eventType: typeof(OrderSent),
    publisherEndpoint: "Sending");

Renamed APIs

Access to settings

The GetSettings extension method has been moved from NServiceBus.Configuration.AdvanceExtensibility to the NServiceBus.Configuration.AdvancedExtensibility namespace.

ContextBag extensions

The RemoveDeliveryConstaint extension method has been renamed to RemoveDeliveryConstraint.

IncomingMessage extensions

The GetMesssageIntent extension method has been renamed to GetMessageIntent.

Pipeline configuration

RegisterStep.IsEnabled has been removed. Instead of overriding this method to disable registration, users should instead not register the steps in the pipeline at all.

StorageType

NServiceBus.Persistence.StorageType has been moved to the root NServiceBus namespace to prevent requiring additional using statements when specifying individual storage types explicitly.

Assembly scanning

Mismatched assemblies

64-bit assemblies are no longer silently excluded from scanning when running in an x86 process. Instead, startup will fail with a BadImageFormatException. Use the exclude API to exclude the assembly and avoid the exception.

AppDomain scanning

AppDomain assemblies are now scanned by default. Use the ScanAppDomainAssemblies API to disable AppDomain scanning.

Unobtrusive mode messages

Unobtrusive mode message types will no longer appear in the list of scanned types. These message types are now loaded dynamically as messages arrive.

Legacy .Retries message receiver

The .Retries message receiver, which was added to assist in migrating from version 5 to version 6, has been removed. The API to disable it has also been removed.

MSMQ

The MSMQ transport is no longer part of the NServiceBus NuGet package. It has been moved into a separate package, NServiceBus.Transport.Msmq.

Provision of PowerShell scripts

Two new scripts, CreateQueues.ps1 and DeleteQueues.ps1, have been added to the NuGet package to facilitate the creation of queues for endpoints during deployment. These scripts are copied to a subfolder called NServiceBus.Transport.Msmq in the output folder of any project referencing it. Browse to the output folder to locate the scripts. For example, bin\Debug\net461\NServiceBus.Transport.Msmq.

A new API, DisableInstaller, can now be used to disable the auto-creation of queues during startup.

New transport configuration API

Passing in the connection string when configuring transports is no longer supported. If the connection string is passed, the following exception will be thrown at endpoint start-up:

System.Exception : Passing in MSMQ settings such as DeadLetterQueue, Journaling etc via a connection string is no longer supported. Use code-level API.

New APIs have been added for each of the settings, namely, DisableDeadLetterQueueing, DisableConnectionCachingForSends, UseNonTransactionalQueues, EnableJournaling and TimeToReachQueue. See the transport configuration documentation for more details on the usage.

MSMQ subscription storage

The default queue for the subscription storage has been switched from NServiceBus.Subscriptions to [EndpointName].Subscriptions if the subscription queue has not been explicitly configured.

However, if a subscription storage queue is not provided during configuration time and if the endpoint detects a local queue in the server called NServiceBus.Subscriptions, an exception will be thrown to prevent potential loss of messages. To prevent this, move the subscription messages to the new queue.

Namespace changes

The MsmqPersistence class and its configuration API, SubscriptionQueue(), have been moved from the NServiceBus.Persistence.Legacy namespace to NServiceBus.

MSMQ persistence was originally put into the legacy namespace because of its limited capabilities in scale-out scenarios with the distributor. Sender-side distribution makes MSMQ persistence a viable persistence mechanism when scaling out MSMQ. It was therefore moved from the legacy namespace and back into NServiceBus.

Default transport

There is no longer a default transport; an exception will be thrown if an endpoint is created or started without configuring a transport.

In NServiceBus version 6 and below, the default transport was MSMQ. To use MSMQ in version 7 and above, reference NServiceBus.Transport.Msmq and configure with:

endpointConfiguration.UseTransport<MsmqTransport>();

Message property encryption

The message property encryption feature has been moved from the NServiceBus package. It is now available as a separate NuGet package, NServiceBus.Encryption.MessageProperty.

See the NServiceBus.Encryption.MessageProperty upgrade guide for more details.

JSON serialization

The JSON serializer has been removed from the NServiceBus package. Use the external JSON serializer available as a separate NuGet package, NServiceBus.Newtonsoft.Json.

See the Json.NET Serializer for more details, including its compatibility with the previously available JSON serializer.

Custom correlation ID

Setting a custom correlation ID is considered dangerous. Therefore, the SendOptions.SetCorrelationId and SendOptions.GetCorrelationId APIs have been removed.

Accessing conversation ID

In NServiceBus version 6, the Conversation Id header on outgoing messages was set within the IOutgoingPhysicalMessageContext pipeline stage. In version 7 and above, the Conversation Id header will be set as part of the IOutgoingLogicalMessageContext stage.

ConfigurationErrorsException

Exceptions of type Exception are now thrown instead of ConfigurationErrorsException. Any try-catch statements catching ConfigurationErrorsException should be updated to catch Exception instead.

Licensing

Machine-wide license locations

License files are now stored on the local file system so that they can accessed by all endpoints running on the machine. By default, endpoints will check the following locations for a license.xml file:

  • {SpecialFolder.LocalApplicationData}\ParticularSoftware
  • {SpecialFolder.CommonApplicationData}\ParticularSoftware

Application-specific license location

Licenses can be shipped along with an endpoint's artifacts. By default, endpoints will look for a license.xml in the applications base directory (AppDomain.CurrentDomain.BaseDirectory).

Registry-based license locations

When running on the .NET Framework, endpoints will continue to search the registry locations for a suitable license.

When running on .NET Core, endpoints will not search the registry, even when running on Windows.

Connection strings

Named connection strings

When running on .NET Core, it is no longer possible to configure a transport's connection using .ConnectionStringName(name). To continue to retrieve the connection string by the named value in the configuration, first retrieve the connection string and then pass it to the .ConnectionString(value) configuration.

When running on the .NET Framework, .ConnectionStringName(name) will continue to work, but the API has been marked with an obsolete warning suggesting to move to the .ConnectionString(value) API.

Implicit "NServiceBus/Transport" connection string use

When running on .NET Core, a connection string named NServiceBus/Transport will no longer be detected automatically. The connection string value must be configured explicitly using .ConnectionString(value).

When running on the .NET Framework, the NServiceBus/Transport connection string will continue to function as per previous versions, however a warning will be logged indicating that it should be explicitly configured instead.

var connection = ConfigurationManager.ConnectionStrings["theConnectionName"];
var connectionString = connection.ConnectionString;
transport.ConnectionString(connectionString);

Installers

NServiceBus version 7 will run installers only when explicitly enabled via the endpointConfiguration.EnableInstallers() API. In previous versions, installers are automatically run when starting the endpoint with a debugger attached; this behavior has been removed in version 7. Therefore, the endpointConfiguration.DisableInstallers() API is obsolete and no longer required.

DistributionStrategy

The string SelectReceiver(string[] receiverAddresses) signature has been removed from the DistributionStrategy base class. When writing a custom distribution strategy, implement the string SelectDestination(DistributionContext context) method instead which provides additional information usable for routing decisions. Receiver addresses can still be accessed via the context.ReceiverAddresses property.

HandleCurrentMessageLater

The IMessageHandlerContext.HandleCurrentMessageLater() method has been deprecated.

To handle the current message later and abort the current processing attempt, throw an exception in the message handler and let recoverability reschedule the message. Note the following restrictions:

  • Retries are enabled only when the transport is configured to use transactions (i.e. anything other than TransportTransactionMode.None.
  • When throwing an exception, the current transaction will be rolled back, causing outgoing messages to be discarded.
  • The retry attempts and delays depend on the specific configuration.
  • Depending on the transport's transaction behavior, the message will reappear at the front or at the back of the queue.

To complete processing of the current message without invoking additional handlers and reprocess it later, send a copy of the current message via IMessageHandlerContext.SendLocal(...). Note the following restrictions:

  • Reusing the incoming message instance is possible, however it does not copy the headers of the incoming message. Headers need to be manually set on the outgoing message via the outgoing headers API.
  • A delay can be added using the send options. For more options see the delayed delivery section.
  • The sent message will be added at the back of the queue.

Default critical error behavior

In NServiceBus version 6 and below, the default behavior was to stop the endpoint when critical errors occur. In version 7 and above, the default behavior is to keep the endpoint running to allow infrastructure (i.e. transports, persisters, etc.) to try to recover from the failure condition. One example is the queuing system being unavailable or not being able to connect to the database.

See the critical errors documentation for details on how to customize this behavior.

Startup diagnostics written to disk

When endpoints start, a diagnostics file is written to disk in a subfolder called .diagnostics. See the startup diagnostics documentation for more details.

Routing for send-only endpoints

Routing messages to the local endpoint or local instance is no longer allowed for send-only endpoints, since they are not able to receive messages. When detected, the following exception is thrown:

System.InvalidOperationException: Cannot route to instances of this endpoint since it's configured to be in send-only mode.

Source Link

As of NServiceBus version 7, all packages support Source Link, a developer productivity feature that allows debugging into NServiceBus code by downloading the source directly from GitHub.

There is currently a bug with Visual Studio 2017 SDK-style projects that prevents Source Link from working when the project targets the .NET Framework. A workaround for the bug is to add the SourceLink.Copy.PdbFiles NuGet package to the project.

Related Articles