Fluentmigrator: DependecyInjection For Migrations

Created on 27 May 2020  路  8Comments  路  Source: fluentmigrator/fluentmigrator

I Make a custom nuget to use in all my projects, inside there is some migrations and works like a charm, but then i tried to hide this migrations making then internal

Obviusly it didn't work hehe

Searching in your source code i finded this

assemblies.SelectMany(a => a.GetExportedTypes()).Where(t => typeof(IMigration).IsAssignableFrom(t) && !t.IsAbstract);

the GetExportedTypes only get public classes and its ok.

so why not inject in AssemblyMigrationSourceItem IEnumerable\ because i can insert my migrations directly in the same service collection! and then mix the injected with what you find in the assemblies.Select if it is needed???

area-DependencyInjection

All 8 comments

@iceoz I'll delegate this question to @fubar-coder . I don't know the precise answer as to "why". It looks like @fubar-coder refactored the code to remove the concept of IAssemblyCollection and replace it with IAssemblySource. I'm not sure why this change was made. It looks like @fubar-coder experimented with a couple of different ways for locating assemblies to scan/decorate, including Scrutor.

If you want to submit a PR:

  1. The PR would need to cover many areas (see below). If you think the "juice is worth the squeeze", I'm happy to merge a PR. However, just looking everywhere we reference GetExportedTypes, it's a lot.
  2. You should probably first lay out a conceptual proposal for what you would do, before diving in and writing a bunch of code. In other words, I would say you identified a limitation in the product, but have not yet identified a solution for that limitation.
  3. It's not clear to me why FluentMigrator handles locating migrations the way that it does: there are different "sources" for different types of migrations, and while its interesting way to do modularity, I have to confess, I have not found it useful and I've been meaning to look into how the code evolved to its present state. In some ways, it seems like IAssemblySource duplicates what Microsoft.Extensions.DependencyInjection.IServiceCollection provides: a way to construct a type universe. Except, for whatever reason, FluentMigrator supports multiple type universes. At the moment I type this, I'm not sure what value our IAssemblySource provides over IServiceCollection, and hope @fubar-coder can help explain.

Searching in your source code i finded this

assemblies.SelectMany(a => a.GetExportedTypes()).Where(t => typeof(IMigration).IsAssignableFrom(t) && !t.IsAbstract);

the GetExportedTypes only get public classes and its ok.

First, thanks for the suggestion to search for that expression. I took it a step further and searched for assemblies.SelectMany(a => a.GetExportedTypes()). Below is my effort to capture each place, with better code highlighting than GitHub default code search.

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/AssemblyCollectionService.cs#L46-L47

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/AssemblyVersionTableMetaDataSourceItem.cs#L48-L51

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/AssemblyMigrationSourceItem.cs#L43-L45

https://github.com/fluentmigrator/fluentmigrator/blob/27eb0110ff14b4d32aed7d316ee5caf4dda20716/src/FluentMigrator.Runner.Core/Initialization/AssemblySourceItem%601.cs#L44-L47

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/AssemblySourceVersionTableMetaDataAccessor.cs#L81-L84

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/AssemblySourceMigrationRunnerConventionsAccessor.cs#L50-L51

https://github.com/fluentmigrator/fluentmigrator/blob/27eb0110ff14b4d32aed7d316ee5caf4dda20716/src/FluentMigrator.Runner.Core/Initialization/AssemblySourceConventionSetAccessor.cs#L81-L84

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner/Generators/MigrationGeneratorFactory.cs#L37-L40

https://github.com/fluentmigrator/fluentmigrator/blob/e82aafa20e6dbe3cefa221303fe23cf8bf59fffd/src/FluentMigrator.Runner.Core/Initialization/MigrationSource.cs#L101-L103

https://github.com/fluentmigrator/fluentmigrator/blob/3aedfcb0858388d96366c42312abe8eac67211c3/src/FluentMigrator.Runner/MaintenanceLoader.cs#L43-L54

@iceoz I added an Architecture Decision Record (ADR) document to the FluentMigrator master branch to lay out some thoughts on dependency injection. Please have a look at the commit above and feel free to add review comments. It might be able to view the HTML version, here, especially the table I created: https://github.com/fluentmigrator/fluentmigrator/blob/master/adr/proposed/DependencyInjection.md#the-list-of-different-things-fluentmigrator-cares-about I still need to make a few more comments to this document.

If you're not familiar with ADRs, you can read about them here: https://labs.spotify.com/2020/04/14/when-should-i-write-an-architecture-decision-record/

IAssemblyCollection was too inflexible and did too much in one place. The IAssemblySource was a replacement that allowed me to implement the fluent API (see .ScanIn) for the configuration of assembly sources. Those interfaces probably should've been internal...

I agree that it's sometimes a mishmash and some things could've done better. Something that was some kind of problem for me was that both migrations and maintenance objects implement the IMigration interface, which doesn't work well with DI.

Thanks, Mark! That makes sense - I was starting to figure that out by seeing how the code evolved from Scrutor to our own scanning extensions. It would almost be nice if Scrutor factored out just the ScanIn API into its own package. Then, I don't think you would have had to write your own, right?

thanks for responding my coment @jzabroski @fubar-coder =) and i can't understand why not use scrutor, in scrutor you can pass a list of assemblies or types to get theirs assemblies, but at the same time scrutor seems to be a little abandoned =/

I don't think Scrutor is abandoned. :) It literally has twice as many downloads as FluentMigrator and is one of the most popular Nuget packages not provided by Microsoft. If that is abandoned then the .NET open source community is in serious trouble lol :)

Hehe, i just say what i think =) and it's a amazing library, but comparared to fluent migration, they have lower code frequency

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Plasma picture Plasma  路  11Comments

tgharold picture tgharold  路  6Comments

biju-ps picture biju-ps  路  10Comments

n1ghtmare picture n1ghtmare  路  5Comments

ondravondra picture ondravondra  路  8Comments