I am using multiple endpoint hosting in the same process with the goal of helping building a redundancy system. One endpoint only receive Start/Stop messages and trigger Start/Stop on the real endpoint with the background worker services. The goal is to stop processing messages and keep it in “idle” state while it is not elected as the main instance, while still having the Windows Service application running and ready to start processing.
Previously, using self-hosting, I could easily create two IEndpointInstance
and call Start/Stop on them as often as I wanted and it worked perfectly. I’m trying to achieve the same goal using the .NET Generic Host and I am having issues.
First, with NServiceBus out of the image, it seems that .NET Generic Host by themselves can’t be stopped and restarted within the same application lifetime or it crash and throw exceptions. I created a StackOverflow question about it here.
So my first instinct as a workaround was to leave the .NET Generic Host running, but using the IServiceProvider
instance to grab every hosted services (mine, and the NServiceBus ones) and call start/stop on them instead.
Problem is, the IServiceProvider.GetService()
method require a type. IEndpointInstance
isn’t registered. When debugging, I can see multiple services registered by NServiceBus:
NServiceBus.HostAwareMessageSession
NServiceBus.Extensions.Hosting.NServiceBusHostedService
NServiceBus.LearningTransportDispatcher
NServiceBus.Hosting.HostInformation
NServiceBus.StorageInitializer.CallInit
I see that NServiceBusHostedService
have a “Endpoint” property that I could probably call Start/Stop on it. Unfortunately, I can’t resolve an instance of this type because it is marked as internal
. This blocks my attempt to retrieve the NServiceBus endpoint.
But still, as a test I called GetService<IHostedService>()
with only this service registered and managed to get the instance of NServiceBusHostedService
anyway (typed as a IHostedService). I can’t access the Endpoint sub-property, but I can call StopAsync/StartAsync on it passing a new CancellationToken. Doing so seems to work for the Stop, but unfortunately when calling Start again afterward I get this exception:
System.Collections.Generic.KeyNotFoundException : 'The given key (NServiceBus.Transport.TransportInfrastructure) was not present in the dictionary.'
So I really don’t think this is the proper method to achieve my goal.
TLDR; Is stopping and restarting endpoint message processing possible to do with the .NET Generic Host method? And how?