gautema/CQRSlite

You can no longer return IServiceProvider from ConfigureServices as in Web example from .NET Core 3

deadwards90 opened this issue · 9 comments

Somewhat related to #32

From .NET Core 3+, you can no longer return IServiceProvider from ConfigureServices, so following the example AspNetCore example, you now end up with two instances of all of the singletons.

Hi. And thanks for the heads up. I'll take a look at it. Have you had a look at the problem and know a way to solve it?

I've had a look at the problem but not quite found a way to solve it.

From what I can tell you now have to do this kind of thing by moving it out of Startup and into the HostBuilder. This is supposed to be to support the new GenericHost they released with .NET Core 3.

They give you this to do it with:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.iserviceproviderfactory-1?view=dotnet-plat-ext-3.0

What I'm struggling with is how to change Provider to work in this way, if that is even what I'm supposed to be changing.

Figured it out (I think).

Just based off the default one that is used under the hood, you should just need to do this now:

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
                .UseServiceProviderFactory(new RouteRegistrarProviderFactory());
    }

    public class RouteRegistrarProviderFactory : IServiceProviderFactory<IServiceCollection>
    {
        public IServiceCollection CreateBuilder(IServiceCollection services)
        {
            return services;
        }

        public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)
        {
            var serviceProvider = containerBuilder.BuildServiceProvider();
            var registrar = new RouteRegistrar(new Startup.Provider(serviceProvider));
            registrar.RegisterInAssemblyOf(typeof(UserCommandHandler));
            return serviceProvider;
        }
    }

And then remove the part from Startup.

I'd make the PR for this but it would require moving everything up to .NET Core 3.

I just started looking at it myself, but haven't come quite as far as you have.

Moving to dotnet core 3 is no problem in the sample. I really appreciate a PR

I'll give it a go later on today / tonight then 👍

I'm working on it now. Check out https://github.com/gautema/CQRSlite/tree/Issue/90 for the progress so far. It seems to be working on my Windows image and my Appveyor build. I'll test a bit more, if you have the time take a look.

Looks almost identical to what I've done, and it appears to be all working fine for me.

Cool. I took a great deal of inspiration from the code you pasted. I'll commit it to master.

I just committed to master. Thanks for all the help with this issue.