gautema / CQRSlite

A lightweight framework to help creating CQRS and Eventsourcing applications in C#
Other
1.1k stars 266 forks source link

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

Closed deadwards90 closed 5 years ago

deadwards90 commented 5 years ago

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.

gautema commented 5 years ago

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?

deadwards90 commented 5 years ago

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.

deadwards90 commented 5 years ago

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.

gautema commented 5 years ago

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

deadwards90 commented 5 years ago

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

gautema commented 5 years ago

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.

deadwards90 commented 5 years ago

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

gautema commented 5 years ago

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

gautema commented 5 years ago

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