Upgrade Version 6 to 7

Component: NServiceBus
This page targets a pre-release version and is subject to change prior to the final release.

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

Config

The Configuration APIs IProvideConfiguration, IConfigurationSource and CustomConfigurationSource have been deprecated. The equivalent code based API can be used instead.

Audit

Configuring Audit via the following APIs have been deprecated:

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

Instead use one of the following: BadImageFormatException

Configure by the code API

7-pre NServiceBus
endpointConfiguration.AuditProcessedMessagesTo(
    auditQueue: "targetAuditQueue",
    timeToBeReceived: TimeSpan.FromMinutes(10));

Read from an AppSettings and configure by the code API

7-pre NServiceBus
<configuration>
  <appSettings>
    <add key="AuditQueue"
         value="targetAuditQueue" />
    <add key="TimeToBeReceived"
         value="00:10:00" />
  </appSettings>
</configuration>
7-pre NServiceBus
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 have been deprecated:

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

Instead use one of the following:

Configure by the code API

7-pre NServiceBus
var logFactory = LogManager.Use<DefaultFactory>();
logFactory.Level(LogLevel.Info);

Read from an AppSettings and configure by the code API

7-pre NServiceBus
<appSettings>
  <add key="LoggingThreshold"
       value="Debug" />
</appSettings>
7-pre NServiceBus
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 have been deprecated:

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

Instead use one of the following:

Configure by the code API

7-pre NServiceBus
endpointConfiguration.SendFailedMessagesTo("error");

Read from an AppSettings and configure by the code API

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

Endpoint Mappings

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

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

It can be replaced with a combination of the following

Command routing

7-pre NServiceBus
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

7-pre NServiceBus
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. More details on advanced access to settings can be found here.

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 a 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.

Legacy .Retries message receiver

The .Retries message receiver 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 called, 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 called, DisableInstaller can now be used to disable the auto-creation of queues during startup.

New Transport Configuration API

Passing in the connection string 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 setting 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 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 changes this and 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, so an exception will be thrown if an endpoint is created or started without configuring a transport.

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

7-pre NServiceBus
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 Versions 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).

The {AppDomain.CurrentDomain.BaseDirectory}\License\License.xml path will no longer be checked.

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

Configuring a transport's connection using .ConnectionStringName(name) has been removed. 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.

Implicit "NServiceBus/Transport" connection string use

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

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

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

Installers

NServiceBus Version 7 will only run installers 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 has been obsoleted and is 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. Be aware of the following restrictions:

  • Retries are only enabled when the transport is configured to use some sort of 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(...). Be aware of 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 Versions 6 and below, the default behavior was to stop the endpoint when critical errors occur. In Versions 7 and above, the default behavior is to keep the endpoint running to allow infrastructure like transports, persisters, etc to try to recover from the failure condition. One example would be 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

As endpoints starts up 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.

Related Articles


Last modified