This is part of the NServiceBus Upgrade Guide from Version 5 to 6, which also includes the following individual upgrade guides for specific components:
Feature Details
- Assembly Scanning Changes in NServiceBus Version 6
- No Async Suffix
- Dependency Injection Changes in NServiceBus Version 6
- Deprecated TransportMessage in NServiceBus Version 6
- Endpoint API changes in NServiceBus Version 6
- Extension Seam Changes in NServiceBus Version 6
- Migrate handlers and sagas to Version 6
- Header API changes in NServiceBus Version 6
- Messaging Changes in NServiceBus Version 6
- Moving away from IBus in Version 6
- Recoverability Changes in Version 6
- Serialization Changes in NServiceBus Version 6
- Subscription Changes in NServiceBus Version 6
- Transaction Configuration Changes in NServiceBus Version 6
Transports
- Azure Service Bus Transport (Legacy) Upgrade Version 6 to 7
- RabbitMQ Transport Upgrade Version 3 to 4
- SQL Server Transport Upgrade Version 2 to 3
- SQL Server Transport Upgrade - Supporting Unicode in Headers
Persistence
- Upgrade from NServiceBus Azure Version 6
- NHibernate Persistence Upgrade Version 6 to 7
- NHibernate Persistence - Resolving incorrect timeout table indexes
- RavenDB Persistence Upgrade from 3 to 4
Hosting
Other
- Moving to the DataBus AzureBlobStorage Package
- Azure Cloud Services Host Upgrade Version 6 to 7
- NServiceBus.Azure package deprecated
- Gateway Upgrade Version 1 to 2
- NServiceBus Testing Upgrade Version 5 to 6
- Callback Changes in NServiceBus Version 6
- Migrating the distributor to use sender-side distribution
- Tool and Helper Changes in NServiceBus Version 6
Endpoint name is mandatory
In NServiceBus versions 6 and above, endpoint name is mandatory.
// For NServiceBus version 6.x
var endpointConfiguration = new EndpointConfiguration("MyEndpointName");
// For NServiceBus version 5.x
var busConfiguration = new BusConfiguration();
busConfiguration.EndpointName("MyEndpointName");
The endpoint name is used as a logical identifier when sending or receiving messages. It is also used for determining the name of the input queue the endpoint will be bound to. See Derived endpoint name for the algorithm used in NServiceBus versions 5 and below to select endpoint name if backwards compatibility is a concern.
Interface changes
The IWantToRunWhenBusStartsAndStops
interface is now obsolete.
If the extensibility provided by IWantToRunWhenBusStartsAndStops
is still required, it can be achieved via other means in the NServiceBus endpoint lifecycle.
Self-hosting
When self-hosting, call any startup code after Endpoint.
and cleanup code after Endpoint.
.
// For NServiceBus version 6.x
var endpointConfiguration = new EndpointConfiguration("EndpointName");
// Custom code before start
var endpointInstance = await Endpoint.Start(endpointConfiguration);
// Custom code after start
// Block the process
// Custom code before stop
await endpointInstance.Stop();
// Custom code after stop
// For NServiceBus version 5.x
var busConfiguration = new BusConfiguration();
// Custom code before start
var startableBus = Bus.Create(busConfiguration);
using (var bus = startableBus.Start())
{
// Custom code after start
// Block the process
// Custom code before stop
}
// Custom code after stop
While the Dispose Pattern can no longer be used (since IEndpointInstance
does not implement IDisposable) this is not a common use case since in most hosting scenarios, the startup code is not in the same method as the shutdown code. For example
- Windows Service Hosting where startup is usually done in ServiceBase.OnStart and shutdown is usually done in ServiceBase.OnStop.
- Web Site or Web Service Hosting where startup is usually done in HttpApplication.Application_Start and shutdown is usually done in HttpApplication.Dispose.
Using NServiceBus.Host
See the upgrade guide for more details on using the new interface provided by the host.
Endpoint name helper
An algorithm is used in NServiceBus version 5 to determine the name of the endpoint if none is provided. If the same behavior is needed in versions 6 and above, this helper class can be used.
public static class EndpointNameHelper
{
public static string GetDefaultEndpointName()
{
var entryType = GetEntryType();
if (entryType != null)
{
var endpointName = entryType.Namespace ?? entryType.Assembly.GetName().Name;
if (endpointName != null)
{
return endpointName;
}
}
throw new Exception("No endpoint name could be derived");
}
static Type GetEntryType()
{
var stackTraceToExamine = new StackTrace();
var entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly?.EntryPoint != null)
{
return entryAssembly.EntryPoint.ReflectedType;
}
StackFrame targetFrame = null;
var stackFrames = new StackTrace().GetFrames();
if (stackFrames != null)
{
targetFrame =
stackFrames.FirstOrDefault(
f => typeof(HttpApplication).IsAssignableFrom(f.GetMethod().DeclaringType));
}
if (targetFrame != null)
{
return targetFrame.GetMethod().ReflectedType;
}
stackFrames = stackTraceToExamine.GetFrames();
if (stackFrames != null)
{
targetFrame =
stackFrames.FirstOrDefault(
f =>
{
var declaringType = f.GetMethod().DeclaringType;
return declaringType != typeof(EndpointConfiguration);
});
}
if (targetFrame == null)
{
targetFrame = stackFrames.FirstOrDefault(
f => f.GetMethod().DeclaringType.Assembly != typeof(EndpointConfiguration).Assembly);
}
if (targetFrame != null)
{
return targetFrame.GetMethod().ReflectedType;
}
throw new Exception("Could not derive EndpointName");
}
}