Skip to content
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

Ability to apply migrations through multiple assemblies #187

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion src/FluentMigrator.Runner/IMigrationRunner.cs
Expand Up @@ -5,7 +5,6 @@ namespace FluentMigrator.Runner
public interface IMigrationRunner
{
IMigrationProcessor Processor { get; }
Assembly MigrationAssembly { get; }
void Up(IMigration migration);
void MigrateUp();
void MigrateUp(long version);
Expand Down
34 changes: 21 additions & 13 deletions src/FluentMigrator.Runner/MigrationLoader.cs
Expand Up @@ -27,29 +27,37 @@ namespace FluentMigrator.Runner
public class MigrationLoader : IMigrationLoader
{
public IMigrationConventions Conventions { get; private set; }
public Assembly Assembly { get; private set; }
public IList<Assembly> Assemblies { get; private set; }
public string Namespace { get; private set; }
public bool LoadNestedNamespaces { get; private set; }
public SortedList<long, IMigration> Migrations { get; private set; }

public MigrationLoader(IMigrationConventions conventions, Assembly assembly, string @namespace)
: this (conventions, new[] { assembly }, @namespace)
{
Conventions = conventions;
Assembly = assembly;
Namespace = @namespace;

Initialize();
}

public MigrationLoader(IMigrationConventions conventions, Assembly assembly, string @namespace, bool loadNestedNamespaces)
: this (conventions, new [] { assembly }, @namespace, loadNestedNamespaces)
{
Conventions = conventions;
Assembly = assembly;
Namespace = @namespace;
LoadNestedNamespaces = loadNestedNamespaces;

Initialize();
}

public MigrationLoader(IMigrationConventions conventions, IEnumerable<Assembly> assemblies, string @namespace, bool loadNestedNamespaces)
{
Conventions = conventions;
Assemblies = assemblies.ToList();
Namespace = @namespace;
LoadNestedNamespaces = loadNestedNamespaces;

Initialize();
}

public MigrationLoader(IMigrationConventions conventions, IEnumerable<Assembly> assemblies, string @namespace)
: this(conventions, assemblies, @namespace, false)
{

}

private void Initialize()
{
Migrations = new SortedList<long, IMigration>();
Expand All @@ -71,7 +79,7 @@ private void Initialize()

public IEnumerable<MigrationMetadata> FindMigrations()
{
IEnumerable<Type> matchedTypes = Assembly.GetExportedTypes().Where(t => Conventions.TypeIsMigration(t));
IEnumerable<Type> matchedTypes = Assemblies.SelectMany(a => a.GetExportedTypes()).Where(t => Conventions.TypeIsMigration(t));

if (!string.IsNullOrEmpty(Namespace))
{
Expand Down
24 changes: 15 additions & 9 deletions src/FluentMigrator.Runner/MigrationRunner.cs
Expand Up @@ -30,7 +30,7 @@ namespace FluentMigrator.Runner
{
public class MigrationRunner : IMigrationRunner
{
private Assembly _migrationAssembly;
private IList<Assembly> _migrationAssemblies;
private IAnnouncer _announcer;
private IStopWatch _stopWatch;
private bool _alreadyOutputPreviewOnlyModeWarning;
Expand All @@ -43,8 +43,14 @@ public class MigrationRunner : IMigrationRunner
public IList<Exception> CaughtExceptions { get; private set; }

public MigrationRunner(Assembly assembly, IRunnerContext runnerContext, IMigrationProcessor processor)
: this(new[] { assembly }, runnerContext, processor)
{
_migrationAssembly = assembly;

}

public MigrationRunner(IEnumerable<Assembly> assemblies, IRunnerContext runnerContext, IMigrationProcessor processor)
{
_migrationAssemblies = assemblies.ToList();
_announcer = runnerContext.Announcer;
Processor = processor;
_stopWatch = runnerContext.StopWatch;
Expand All @@ -56,9 +62,9 @@ public MigrationRunner(Assembly assembly, IRunnerContext runnerContext, IMigrati
if (!string.IsNullOrEmpty(runnerContext.WorkingDirectory))
Conventions.GetWorkingDirectory = () => runnerContext.WorkingDirectory;

VersionLoader = new VersionLoader(this, _migrationAssembly, Conventions);
MigrationLoader = new MigrationLoader(Conventions, _migrationAssembly, runnerContext.Namespace);
ProfileLoader = new ProfileLoader(runnerContext, this, Conventions);
VersionLoader = new VersionLoader(this, _migrationAssemblies, Conventions);
MigrationLoader = new MigrationLoader(Conventions, _migrationAssemblies, runnerContext.Namespace);
ProfileLoader = new ProfileLoader(runnerContext, this, _migrationAssemblies, Conventions);
}

public IVersionLoader VersionLoader { get; set; }
Expand Down Expand Up @@ -267,9 +273,9 @@ public void RollbackToVersion(long version, bool useAutomaticTransactionManageme
}
}

public Assembly MigrationAssembly
public IList<Assembly> MigrationAssemblies
{
get { return _migrationAssembly; }
get { return _migrationAssemblies; }
}

public void Up(IMigration migration)
Expand All @@ -279,7 +285,7 @@ public void Up(IMigration migration)

CaughtExceptions = new List<Exception>();

var context = new MigrationContext(Conventions, Processor, MigrationAssembly);
var context = new MigrationContext(Conventions, Processor, migration.GetType().Assembly);
migration.GetUpExpressions(context);

_stopWatch.Start();
Expand All @@ -297,7 +303,7 @@ public void Down(IMigration migration)

CaughtExceptions = new List<Exception>();

var context = new MigrationContext(Conventions, Processor, MigrationAssembly);
var context = new MigrationContext(Conventions, Processor, migration.GetType().Assembly);
migration.GetDownExpressions(context);

_stopWatch.Start();
Expand Down
37 changes: 22 additions & 15 deletions src/FluentMigrator.Runner/ProfileLoader.cs
Expand Up @@ -9,17 +9,22 @@ namespace FluentMigrator.Runner
{
public class ProfileLoader : IProfileLoader
{
public ProfileLoader(IRunnerContext runnerContext, IMigrationRunner runner, IMigrationConventions conventions)
public ProfileLoader(IRunnerContext runnerContext, IMigrationRunner runner, Assembly assembly, IMigrationConventions conventions)
: this(runnerContext, runner, new[] { assembly }, conventions)
{
Runner = runner;
Assembly = runner.MigrationAssembly;
Profile = runnerContext.Profile;
Conventions = conventions;

Initialize();
}

private Assembly Assembly { get; set; }
public ProfileLoader(IRunnerContext runnerContext, IMigrationRunner runner, IEnumerable<Assembly> assemblies, IMigrationConventions conventions)
{
Runner = runner;
Assemblies = assemblies.ToList();
Profile = runnerContext.Profile;
Conventions = conventions;

Initialize();
}

private IList<Assembly> Assemblies { get; set; }
private string Profile { get; set; }
protected IMigrationConventions Conventions { get; set; }
private IMigrationRunner Runner { get; set; }
Expand All @@ -31,21 +36,23 @@ private void Initialize()
_profiles = new List<IMigration>();

if (!string.IsNullOrEmpty(Profile))
_profiles = FindProfilesIn(Assembly, Profile);
_profiles = FindProfilesIn(Assemblies, Profile);
}

public IEnumerable<IMigration> FindProfilesIn(Assembly assembly, string profile)
{
IEnumerable<Type> matchedTypes = assembly.GetExportedTypes()
IEnumerable<Type> matchedTypes = assembly.GetExportedTypes()
.Where(t => Conventions.TypeIsProfile(t) && t.GetOneAttribute<ProfileAttribute>().ProfileName.ToLower() == profile.ToLower());

foreach (Type type in matchedTypes)
{
yield return type.Assembly.CreateInstance(type.FullName) as IMigration;
}
return matchedTypes.Select(type => type.Assembly.CreateInstance(type.FullName) as IMigration);
}

public IEnumerable<IMigration> Profiles
public IEnumerable<IMigration> FindProfilesIn(IEnumerable<Assembly> assemblies, string profile)
{
return assemblies.SelectMany(assembly => FindProfilesIn(assembly, profile));
}

public IEnumerable<IMigration> Profiles
{
get
{
Expand Down
13 changes: 9 additions & 4 deletions src/FluentMigrator.Runner/VersionLoader.cs
Expand Up @@ -13,10 +13,16 @@ namespace FluentMigrator.Runner
public class VersionLoader : IVersionLoader
{
public VersionLoader(IMigrationRunner runner, Assembly assembly, IMigrationConventions conventions)
: this(runner, new[] { assembly }, conventions)
{

}

public VersionLoader(IMigrationRunner runner, IEnumerable<Assembly> assemblies, IMigrationConventions conventions)
{
Runner = runner;
Processor = runner.Processor;
Assembly = assembly;
Assemblies = assemblies.ToList();

Conventions = conventions;
VersionTableMetaData = GetVersionTableMetaData();
Expand All @@ -25,12 +31,11 @@ public VersionLoader(IMigrationRunner runner, Assembly assembly, IMigrationConve

LoadVersionInfo();
}

protected VersionSchemaMigration VersionSchemaMigration { get; set; }

private IVersionInfo _versionInfo;
public IMigrationRunner Runner { get; set; }
protected Assembly Assembly { get; set; }
protected IList<Assembly> Assemblies { get; set; }
public IVersionTableMetaData VersionTableMetaData { get; private set; }
private IMigrationConventions Conventions { get; set; }
private IMigrationProcessor Processor { get; set; }
Expand All @@ -47,7 +52,7 @@ public void UpdateVersionInfo(long version)

public IVersionTableMetaData GetVersionTableMetaData()
{
Type matchedType = Assembly.GetExportedTypes().Where(t => Conventions.TypeIsVersionTableMetaData(t)).FirstOrDefault();
var matchedType = Assemblies.SelectMany(a => a.GetExportedTypes()).Where(t => Conventions.TypeIsVersionTableMetaData(t)).FirstOrDefault();

if (matchedType == null)
{
Expand Down
2 changes: 1 addition & 1 deletion src/FluentMigrator.Tests/Unit/MigrationRunnerTests.cs
Expand Up @@ -218,7 +218,7 @@ private string containsAll(params string[] words)
[Test]
public void LoadsCorrectCallingAssembly()
{
_runner.MigrationAssembly.ShouldBe(Assembly.GetAssembly(typeof(MigrationRunnerTests)));
_runner.MigrationAssemblies.ShouldContain(Assembly.GetAssembly(typeof(MigrationRunnerTests)));
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions src/FluentMigrator.Tests/Unit/ProfileLoaderTests.cs
Expand Up @@ -20,9 +20,9 @@ public void BlankProfileDoesntLoadProfiles()

_runnerContextMock.Setup(x => x.Profile).Returns(string.Empty);
//_runnerContextMock.VerifyGet(x => x.Profile).Returns(string.Empty);
_runnerMock.SetupGet(x => x.MigrationAssembly).Returns(typeof(MigrationRunnerTests).Assembly);
//_runnerMock.SetupGet(x => x.MigrationAssembly).Returns(typeof(MigrationRunnerTests).Assembly);

var profileLoader = new ProfileLoader(_runnerContextMock.Object, _runnerMock.Object, _conventionsMock.Object);
var profileLoader = new ProfileLoader(_runnerContextMock.Object, _runnerMock.Object, typeof(MigrationRunnerTests).Assembly, _conventionsMock.Object);

profileLoader.ApplyProfiles();

Expand Down