This is part of the NServiceBus Upgrade Guide from Version 6 to 7, which also includes the following individual upgrade guides for specific components:
Transports
- Migrating MSMQ subscription messages
- Azure Service Bus Transport (Legacy) Upgrade Version 7 to 8
- Azure Storage Queues Transport Upgrade Version 7 to 8
- RabbitMQ Transport Upgrade Version 4 to 5
- SQL Server Transport Upgrade Version 3 to 4
Persistence
Hosting
Other
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.configconfigSections
- Returning an
AuditConfig
from anIConfigurationSource
HKEY_LOCAL_MACHINE\
registry keySOFTWARE\ ParticularSoftware\ ServiceBus\ AuditQueue
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.configconfigSections
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.configconfigSections
- Returning a
MessageForwardingInCaseOfFaultConfig
from anIConfigurationSource
HKEY_LOCAL_MACHINE\
registry keySOFTWARE\ ParticularSoftware\ ServiceBus\ ErrorQueue
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/
in an app.configMessageEndpointMappings configSections
- Returning a
UnicastBusConfig
from anIConfigurationSource
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.
to the NServiceBus.
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.
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.
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 .
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.
and DeleteQueues.
, 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.
in the output folder of any project referencing it. Browse to the output folder to locate the scripts. For example, bin\
.
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.
to [EndpointName].
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.
, 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.
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.
.
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.
and SendOptions.
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.
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.
in the applications base directory (AppDomain.
).
The {AppDomain.
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
When running on .NET Core, it is no longer possible to configure a transport's connection using .
. 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 .
configuration.
When running on the .NET Framework, .
will continue to work, but the API has been marked with an obsolete warning suggesting to move to the .
API.
Implicit "NServiceBus/Transport" connection string use
When running on .NET Core, a connection string named NServiceBus/
will no longer be detected automatically. The connection string value must be configured explicitly using .
.
When running on the .NET Framework, the NServiceBus/
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.
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.
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.
property.
HandleCurrentMessageLater
The IMessageHandlerContext.
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.
. 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 .
. 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.
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.