Using NServiceBus with an ASMX web service

61 views Asked by At

I have legacy code base running a .Net 4.8 ASMX web service (not WCF based). I need to send messages using NServiceBus, but I cannot find a way to resolve any of the NServiceBus objects that I need (ITransactionalSession, IMessageSession). This is straightforward in a modern application using DI, but I am stuck in legacy land where that is non-existent. Ideally, I want to also take advantage of features like the outbox and transactional messaging to prevent ghost messages and zombie records.

I found this example from David Boike (a developer at Particular), but it is over 12 years (and 6 versions) old, so I'm hesitant to follow it too closely. I am still reviewing it to see what I can glean, but I'm hoping that this community can provide some more up-to-date suggestions.

I am currently pulling in NSB 8.x (the most recent), but I would be willing to consider downgrading to a previous version if it supports .asmx services better while still minimizing any security considerations.

Update: Thanks to Dennis pointing out self-hosting below, I found Externally Managed Mode which allows me to create the service collection and manage its lifetime. I think this sample is still non-transactional (i.e. no transactional session/outbox support), and I do not understand why the message session is registered as a singleton instead of as a scoped dependency.

This is what my code currently looks like:

const string endpointName = "MyEndpoint";
var endpoint = new EndpointConfiguration(endpointName);
// ... other configurations
var persistence = endpoint.UsePersistence<SqlPersistence>();
persistence.SqlDialect<SqlDialect.MsSqlServer>();
persistence.ConnectionBuilder(() => new SqlConnection(connectionString));
persistence.EnableTransactionalSession();
endpoint.EnableOutbox();

var services = new ServiceCollection();
var startable = EndpointWithExternallyManagedContainer.Create(endpoint, services);
var serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions
            {
                ValidateOnBuild = true
            });

services.AddSingleton(p => startable.MessageSession.Value);
_endpointInstance = startable.Start(serviceProvider).ConfigureAwait(false).GetAwaiter().GetResult();

Is there anything wrong with registering the MessageSession as a scoped dependency? Or am I incorrect in my assumption that it would need to be a scoped dependency to support a transactional session/outbox?

1

There are 1 answers

1
Dennis van der Stelt On BEST ANSWER

You're probably looking for "self hosting". You'll end up with an IMessageSession that you can store somewhere or have it injected in places where you want it.