.NET Generic Host for .NET Core Handlers

Hi All,

Been using NServiceBus for the last couple of months with .NET Core, and it’s been great.

We have a dedicated handler project for our handlers, and this works well.

One thing I don’t like (coming as a non .NET developer) is how it’s done.

We have our Program.cs that uses Autofac, and looks like the following:

namespace Foobar.Handlers
{
    internal class Program
    {
        private static async Task Main()
        {
            var endpointConfiguration = FoobarEndpoint.Setup();

            var builder = new ContainerBuilder();

            IEndpointInstance endpoint = null;
            builder.Register(x => endpoint)
                .As<IEndpointInstance>()
                .SingleInstance();

            var fooClient = new FooClient();
            builder.RegisterInstance<IFooClient>(fooClient);

            var container = builder.Build();

            endpointConfiguration.UseContainer<AutofacBuilder>(customizations =>
            {
                customizations.ExistingLifetimeScope(container);
            });

            endpoint = await Endpoint.Start(endpointConfiguration)
                .ConfigureAwait(false);
            Thread.Sleep(Timeout.Infinite);
            Log.CloseAndFlush();
        }
    }
}

This is just a simple example, but it works quite well. The concerns I have about this are to do with teardown, but it’s not much of an issue now (in development) and will add teardown as needed.

However, we recently started trialing .NET Generic Host for another console app, and it’s been working well.

That’s when I started to do some digging into using this, as I believe it could be quite a good solution for hosting endpoints, as it has features like logging, configuration, DI, start/stop handlers/etc.

Has anyone used this, or have any recommendations?

Hi Josh,
Sorry for the late reply. We are actively tracking the Generic Host and think it is a promising piece of technology. Depending on how it gets adopted we might even be evaluating it later as one of our default hosting choices. That being said right now it is a bit too early to jump to conclusions from our side.

But as you said it is a great choice for hosting endpoints. You can use the IHostedService abstraction to start and stop endpoints or even come up with generic option approaches for multi-endpoint hosting.

Regards
Daniel

Any progress on adopting the generic hosting pattern? I have been digging through NServiceBus documentation, Autofac and of course the DI included with .NET. Trying to determine which piece of each documentation applies to a good final product has been a frustrating process. If anyone has a good example of this use case it would be really helpful.

Thanks.

Hi Craig

The better IServiceCollection is being worked on. To quote @mauroservienti

It’s a work in progress that will be fully enabled by the upcoming 7.2 release. Here is the documentation about externally managed containers and a sample showing how to use it with ASP.Net Core.

That being said already today you can use the GenericHost.

See

and here the code

This crazy bit of code was only added to deal with the difference between webhost builder in ASP.NET Core 2.2 and the GenericHost

With ASP.NET Core 3.0 or just the GenericHost this part can be removed.

Regards
Daniel

Thank you for getting back to me. I came up with a very similar solution using the IHostedService interface. I would appreciate your opinion on this approach. My hosted service class inherits EndpointConfiguration and implements IHostedService. Everything is injected into the constructor and the service is started on StartAsync and stopped in the method StopAsync. Seems to work pretty well. Of course my only concern is if I’m making the right choice of hosting multiple endpoints inside a single process. I don’t intend to have hundreds of endpoints running in the background of a single process but maybe a few related ones. Kind of goes against the ‘micro-service’ architecture principles but it does reduce the amount of effort for CI/CD to our on premises system. If we were deploying to the cloud and managing these services using Kubernetes I would probably go with the single enpoint per host approach. Thoughts?

Hi Craig

I’d be curious how you configure the multiple endpoints so that they don’t pick up handlers that don’t belong to them. I’m wondering if the hassle of configuring assembly scanning like mentioned in

is worth avoiding the CI/CD concern you mentioned. To me with the generic host I would imagine you could even have a simple CI/CD template that gets used whenever you create a new endpoint. Where do you exactly see challenges with CI/CD that pushes you down the path of having multiple endpoints in the same process?

Regards
Daniel

Any ETA on 7.2 being released?

The work is taking place as we “speak” and should be out within a week or two, assuming testing doesn’t uncover additional time consuming work.

It’s out, see

https://discuss.particular.net/t/nservicebus-7-2-0-minor-release-available/1445/2

Regards
Daniel

Thanks, I am upgrading the nuget package references as I type.