New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable FluentMigrator extensibility with new IRunnerFactory #287
Conversation
…ed they're called after derived constructors.
…s; + code documentation.
…ersioning isn't used in this unit test, the version table is never created).
@Pathoschild What is difference between this and using a versionmetadata per namespace ? (not sure if the versionmetadata is supported allready per namespace) |
Hi @tommarien. I didn't see any per-namespace version metadata; the schema name is hardcoded to an empty string. The current version loader scans one assembly for the first type matching the The factory enables extensibility beyond this particular problem. FluentMigrator currently uses interfaces and |
Conflicts: src/FluentMigrator.Runner/FluentMigrator.Runner.csproj src/FluentMigrator.Runner/Initialization/IRunnerContext.cs src/FluentMigrator.Runner/Initialization/RunnerContext.cs src/FluentMigrator.Runner/MigrationLoader.cs src/FluentMigrator.Runner/MigrationRunner.cs src/FluentMigrator.Tests/Unit/MigrationLoaderTests.cs src/FluentMigrator.Tests/Unit/MigrationRunnerTests.cs src/FluentMigrator/FluentMigrator.csproj src/FluentMigrator/Infrastructure/IMigrationContext.cs src/FluentMigrator/Infrastructure/MigrationContext.cs src/FluentMigrator/VersionTableInfo/DefaultVersionTableMetaData.cs
I'm looking at this PR again in connection to #290 and allowing users to set their own MigrationConventions. It's very hard for me to say if this extra layer of factories is needed or not. For the main use case of executing migrations it's not, so it depends on how much people want to customize MigrationRunner. I'm leaning towards the convention based approach of scanning the target assembly for a class that implements IMigrationConventions rather than using a factory. Another option is allowing more dependency injection via the constructor which would mean a new constructor where you could pass in your own version of the dependencies (VersionLoader, ProfileLoader, MigrationInformationLoader etc.) To be honest this approach feels much more explicit than fetching dependencies from a factory via runner context in the constructor. BTW, thanks for the pull request and sorry it's taken so long to process it. What do you think, @tommarien? |
@daniellee conventionel seems like the correct option if you like at the existing code base, for instance iversionmetadata etc. The extra constructor seems a little overcomplicated. |
@tommarien The convention based approach does not help in the example in this PR. You won't be able to mix in something from the ApplicationContext as @Pathoschild does. So I can see the point of this. I suppose you could set the ApplicationContext on the MigrationConventions class to make it available and that way even users who are executing migrations via one of the runners would have access to it. |
Closing to old pr's, sorry about this |
In order to support overloading the default VersionTableMetadata. Enables runtime configuration of VersionTableMetadata schema and version table can be dynamically configured. related issues: fluentmigrator#488 fluentmigrator#287
These changes let developers extend FluentMigrator in their application by creating an instance of
IRunnerFactory
, which constructs loader instances for FluentMigrator. If no factory is provided, FluentMigrator will automatically use theDefaultRunnerFactory
which constructs the same objects as the current code does.Example
We have a multitenant application which uses one schema per tenant, but FluentMigrator stores its version information once per database (in
dbo.versioninfo
). With the new code, we can easily override this default behaviour.First, create a custom factory which overrides the behaviour we're interested in (the version loader). In this example, we use the application context to set the version table's schema.
Then just give the factory to the runner:
And now FluentMigrator handles migrations on a per-schema basis. Whee!
Effects on current uses
This shouldn't affect any existing behaviour; by default the same objects are constructed, but they're done through the
DefaultRunnerFactory
instead of manually. We're successfully using the example above in our application, and all relevant unit tests pass. (A few tests fail due to missing dependencies like MySQL.)The only significant change is that the
VersionLoader
now lazily initializes the version table, instead of doing it immediately in the constructor. This is needed to let custom implementations override the default behaviour in their own constructors. This shouldn't affect any existing behaviour, since the version information is accessed (and therefore initialized) early by the runners.