Separate dependency injection for framework and migrations
See original GitHub issueWhen using third party dependency injection frameworks together with .NET Core, you’ll end up with two IOC containers. One provided by Microsoft for framework dependencies, and one for the application dependencies. I’ll link to some articles of why that is: https://simpleinjector.readthedocs.io/en/latest/servicecollectionintegration.html https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.0#default-service-container-replacement
Anyway, it would be nice to be able to explicitly set the implementation of IServiceProvider for the migrations dependency injection. One could argue that the FluentMigration framework IOC registrations belong to the framework of the application, and that the migrations, which are custom written by the integrator, belongs to the applications IOC registrations, and therefor it makes sense being able to separate them.
It is doable already, but the solution becomes quite hacky and dependable on that the registration of the MigrationSource is done accordingly to FluentMigratorServiceCollectionExtensions.AddFluentMigratorCore.
internal static class MigrationRunnerBuilderExtensions
{
internal static IMigrationRunnerBuilder UseSimpleInjectorForMigrationDependencies(
this IMigrationRunnerBuilder migrationRunnerBuilder,
Container container)
{
// In order to use simple injector as dependency resolver, the migration source needs to be overridden.
// The overridden registration can be found here:
// https://github.com/fluentmigrator/fluentmigrator/blob/ab8e602b2a84f529812ef10791bed4740522d2ed/src/FluentMigrator.Runner/FluentMigratorServiceCollectionExtensions.cs#L89
migrationRunnerBuilder.Services.Replace(new ServiceDescriptor(typeof(IMigrationSource),
serviceProvider => new MigrationSource(
serviceProvider.GetRequiredService<IAssemblySource>(),
serviceProvider.GetRequiredService<IMigrationRunnerConventions>(),
container,
serviceProvider.GetServices<IMigrationSourceItem>()), ServiceLifetime.Scoped));
return migrationRunnerBuilder;
}
Issue Analytics
- State:
- Created 4 years ago
- Comments:8
Top GitHub Comments
I read it, but I need time to think. I respect SimpleInjector authors.
My initial thoughts are: I thought by Microsoft DI existing and ASP.NET Core eliminating static state, we had gotten rid of “DI tunneling” issues (e.g., recording CreatedBy on a EF object using ASP.NET Identity in ASP.NET Classic required tunneling because ASP.NET threading model doesn’t gaurantee you’ll be on the same thread throughout a request’s lifecycle, and if you wanted to add EF objects to a database in parallel, you had to use multiple threads, which broke the ASP.NET Classic Identity chain). After reading the SimpleInjector article, it seems it merely pushed some tunneling up a level. It’s cleaner, but still exists. As best as I can tell, it has to exist.
The remaining questions are likely around this piece of the article:
finally:
I think the general intent is to do something similar to UseSimpleInjector. In that sense, I guess we come full circle and I’m starting to see how your “hack” code above can be cleaned up a bit and generalized.
Thank you, that was a very helpful summary. Sorry for my spastic reply. It takes time going through the daily churn of new issues on this project and sometimes I make inaccurate first guesses as to what the problem is.