AutoMapper / AutoMapper.Collection.EFCore

EFCore support for AutoMapper.Collections

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MapperConfigurationExpressionExtensions.UseEntityFrameworkCoreModel may dispose services in service provider

tkolo opened this issue · comments

commented

In MapperConfigurationExpressionExtensions.cs#33 you create a service provider in using block which eventually calls Dispose() on it. That messes up disposable services registered as singletons in the container. I think you're missing a CreateScope() call there.

Regarding to the code it is building an own IServiceProvider from the IServiceCollection and passing that into next method that is creating a scope on the service provider that is used to fetch the IModel.

Both method UseEntityFrameworkCoreModel that takes the IServiceCollection/IServiceProvider is disposing the objects that they are creating.

Do you have any issues from that we disposing the objects? Can you provide a gist with code or a test-case that shows the problem in that case?

commented

Do you have any issues from that we disposing the objects?

Yes, it dispoed Serilog's ILoggerFactory which is registered singleton. I found this because suddely logging stopped working in my project

Can you provide a gist with code or a test-case that shows the problem in that case?

If you need me to, I can try to reproduce it in some simple project

Yes, please. It will help to better understand the reason of the problem and find an working fix.

commented

BugRepro.zip
Attatched a project that reproduces the issue. The key parts of the code are:

  • the call to UseEntityFrameworkCoreModel() in Startup.cs#35
  • the fact that ApplicationDbContext depends on TestService (which in my original project is Serilog logger)
  • the fact that Startup.Configure() needs IMapper instance while isn't required to reproduce it, it makes the issue worse by disposing the service very early in application lifetime. If absent, the dispose will be postponed to first time IMapper is required (in case of this repro project, first call to ValuesController)

Changing Startup.cs#35 to config.UseEntityFrameworkCoreModel<ApplicationDbContext>((IServiceProvider) services.BuildServiceProvider().CreateScope()); resolves the issue.

Use the overload of the services.AddAutoMapper that includes the service provider as the following during the setup.

            services.AddAutoMapper((serviceProvider, config) =>
            {
                config.AddCollectionMappers();
                config.UseEntityFrameworkCoreModel<ApplicationDbContext>(serviceProvider);
            });
commented

I ended up doing just that, thanks for the tip.