MapperConfigurationExpressionExtensions.UseEntityFrameworkCoreModel may dispose services in service provider
tkolo opened this issue · comments
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?
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.
BugRepro.zip
Attatched a project that reproduces the issue. The key parts of the code are:
- the call to
UseEntityFrameworkCoreModel()
inStartup.cs#35
- the fact that
ApplicationDbContext
depends onTestService
(which in my original project is Serilog logger) - the fact that
Startup.Configure()
needsIMapper
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 timeIMapper
is required (in case of this repro project, first call toValuesController
)
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);
});
I ended up doing just that, thanks for the tip.