Resvolution - MigrationResolver
This commit is contained in:
@@ -457,10 +457,8 @@ namespace Umbraco.Core
|
||||
() => PluginManager.ResolvePackageActions());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
Container, ProfilingLogger.Logger,
|
||||
() => PluginManager.ResolveTypes<IMigration>());
|
||||
|
||||
MigrationCollectionBuilder.Register(Container)
|
||||
.AddProducer(() => PluginManager.ResolveTypes<IMigration>());
|
||||
|
||||
// need to filter out the ones we dont want!!
|
||||
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
|
||||
|
||||
@@ -428,7 +428,7 @@ namespace Umbraco.Core
|
||||
/// This assumes all of the previous checks are done!
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal Result UpgradeSchemaAndData(IMigrationEntryService migrationEntryService, IMigrationResolver migrationResolver)
|
||||
internal Result UpgradeSchemaAndData(IMigrationEntryService migrationEntryService, MigrationCollectionBuilder builder)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -487,7 +487,7 @@ namespace Umbraco.Core
|
||||
|
||||
//DO the upgrade!
|
||||
|
||||
var runner = new MigrationRunner(migrationResolver, migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), GlobalSettings.UmbracoMigrationName);
|
||||
var runner = new MigrationRunner(builder, migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), GlobalSettings.UmbracoMigrationName);
|
||||
|
||||
var migrationContext = new MigrationContext(database, _logger);
|
||||
var upgraded = runner.Execute(migrationContext /*, true*/);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
// exists so the builder can be mocked in tests
|
||||
public interface IMigrationCollectionBuilder
|
||||
{
|
||||
MigrationCollection CreateCollection(IMigrationContext context);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
public interface IMigrationResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the migrations
|
||||
/// </summary>
|
||||
IEnumerable<IMigration> GetMigrations(IMigrationContext migrationContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
public class MigrationCollection : BuilderCollectionBase<IMigration>
|
||||
{
|
||||
public MigrationCollection(IEnumerable<IMigration> items)
|
||||
: base(items)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using LightInject;
|
||||
using Umbraco.Core.DependencyInjection;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
public class MigrationCollectionBuilder : LazyCollectionBuilderBase<MigrationCollectionBuilder, MigrationCollection, IMigration>, IMigrationCollectionBuilder
|
||||
{
|
||||
public MigrationCollectionBuilder(IServiceContainer container)
|
||||
: base(container)
|
||||
{
|
||||
// because collection builders are "per container" this ctor should run only once per container.
|
||||
//
|
||||
// note: constructor dependencies do NOT work with lifetimes other than transient
|
||||
// see https://github.com/seesharper/LightInject/issues/294
|
||||
//
|
||||
// resolve ctor dependency from GetInstance() runtimeArguments, if possible - 'factory' is
|
||||
// the container, 'info' describes the ctor argument, and 'args' contains the args that
|
||||
// were passed to GetInstance() - use first arg if it is the right type.
|
||||
//
|
||||
// for IMigrationContext
|
||||
container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IMigrationContext : null);
|
||||
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
// nothing - do not register the collection
|
||||
}
|
||||
|
||||
protected override MigrationCollectionBuilder This => this;
|
||||
|
||||
public MigrationCollection CreateCollection(IMigrationContext context)
|
||||
{
|
||||
return new MigrationCollection(CreateItems(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LightInject;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IMigrations
|
||||
/// </summary>
|
||||
internal class MigrationResolver : ContainerLazyManyObjectsResolver<MigrationResolver, IMigration>, IMigrationResolver
|
||||
{
|
||||
|
||||
public MigrationResolver(IServiceContainer container, ILogger logger, Func<IEnumerable<Type>> migrations)
|
||||
: base(container, logger, migrations, ObjectLifetimeScope.Transient) // do NOT change .Transient, see CreateValues below
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This creates the instances in a child IoC container, everytime GetMigrations is called, a child container
|
||||
/// is created, the types are added to it and resolved and the child container is diposed.
|
||||
/// </summary>
|
||||
/// <param name="scope"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This doesn't need to be thread safe because Migration instances are transient anyways
|
||||
/// </remarks>
|
||||
protected override IEnumerable<IMigration> CreateValues(ObjectLifetimeScope scope)
|
||||
{
|
||||
// note: constructor dependencies do NOT work with lifetimes other than transient
|
||||
// see https://github.com/seesharper/LightInject/issues/294
|
||||
EnsureTypesRegisterred(scope, container =>
|
||||
{
|
||||
// resolve ctor dependency from GetInstance() runtimeArguments, if possible - 'factory' is
|
||||
// the container, 'info' describes the ctor argument, and 'args' contains the args that
|
||||
// were passed to GetInstance() - use first arg if it is the right type,
|
||||
//
|
||||
// for IMigrationContext
|
||||
container.RegisterConstructorDependency((factory, info, args) => args.Length > 0 ? args[0] as IMigrationContext : null);
|
||||
});
|
||||
|
||||
var arg = new object[] { _migrationContext };
|
||||
return InstanceTypes.Select(x => (IMigration) Container.GetInstance(x, arg));
|
||||
}
|
||||
|
||||
private IMigrationContext _migrationContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the migrations
|
||||
/// </summary>
|
||||
public IEnumerable<IMigration> GetMigrations(IMigrationContext migrationContext)
|
||||
{
|
||||
//set the current context to use to create the values
|
||||
_migrationContext = migrationContext;
|
||||
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
/// </summary>
|
||||
public class MigrationRunner
|
||||
{
|
||||
private readonly IMigrationResolver _resolver;
|
||||
private readonly IMigrationCollectionBuilder _builder;
|
||||
private readonly IMigrationEntryService _migrationEntryService;
|
||||
private readonly ILogger _logger;
|
||||
private readonly SemVersion _currentVersion;
|
||||
@@ -30,16 +30,16 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
private readonly string _productName;
|
||||
private readonly IMigration[] _migrations;
|
||||
|
||||
public MigrationRunner(IMigrationResolver resolver, IMigrationEntryService migrationEntryService, ILogger logger, SemVersion currentVersion, SemVersion targetVersion, string productName, params IMigration[] migrations)
|
||||
public MigrationRunner(IMigrationCollectionBuilder builder, IMigrationEntryService migrationEntryService, ILogger logger, SemVersion currentVersion, SemVersion targetVersion, string productName, params IMigration[] migrations)
|
||||
{
|
||||
if (resolver == null) throw new ArgumentNullException("resolver");
|
||||
if (builder == null) throw new ArgumentNullException("builder");
|
||||
if (migrationEntryService == null) throw new ArgumentNullException("migrationEntryService");
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (currentVersion == null) throw new ArgumentNullException("currentVersion");
|
||||
if (targetVersion == null) throw new ArgumentNullException("targetVersion");
|
||||
Mandate.ParameterNotNullOrEmpty(productName, "productName");
|
||||
|
||||
_resolver = resolver;
|
||||
_builder = builder;
|
||||
_migrationEntryService = migrationEntryService;
|
||||
_logger = logger;
|
||||
_currentVersion = currentVersion;
|
||||
@@ -159,7 +159,7 @@ namespace Umbraco.Core.Persistence.Migrations
|
||||
protected IMigration[] FindMigrations(IMigrationContext context)
|
||||
{
|
||||
//MCH NOTE: Consider adding the ProductName filter to the Resolver so we don't get a bunch of irrelevant migrations
|
||||
return _migrations ?? _resolver.GetMigrations(context).ToArray();
|
||||
return _migrations ?? _builder.CreateCollection(context).ToArray();
|
||||
}
|
||||
|
||||
internal void InitializeMigrations(
|
||||
|
||||
@@ -271,6 +271,9 @@
|
||||
<Compile Include="Models\PublishedContent\PropertyResult.cs" />
|
||||
<Compile Include="Models\PublishedContent\PropertyResultType.cs" />
|
||||
<Compile Include="Persistence\IUmbracoDatabaseAccessor.cs" />
|
||||
<Compile Include="Persistence\Migrations\IMigrationCollectionBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationCollection.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationCollectionBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\AddContentNuTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionEight\RefactorXmlColumns.cs" />
|
||||
<Compile Include="Persistence\ThreadStaticUmbracoDatabaseAccessor.cs" />
|
||||
@@ -327,7 +330,6 @@
|
||||
<Compile Include="Persistence\UnitOfWorkExtensions.cs" />
|
||||
<Compile Include="Persistence\Mappers\AuditItemMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\IMappingResolver.cs" />
|
||||
<Compile Include="Persistence\Migrations\IMigrationResolver.cs" />
|
||||
<Compile Include="Persistence\NPocoDatabaseTypeExtensions.cs" />
|
||||
<Compile Include="Persistence\Querying\IQueryFactory.cs" />
|
||||
<Compile Include="Persistence\Querying\QueryFactory.cs" />
|
||||
@@ -823,7 +825,6 @@
|
||||
<Compile Include="Persistence\Migrations\MigrationBase.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationContext.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationExpressionBase.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationResolver.cs" />
|
||||
<Compile Include="Persistence\Migrations\MigrationRunner.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Alter\AlterSyntaxBuilder.cs" />
|
||||
<Compile Include="Persistence\Migrations\Syntax\Alter\Column\AlterColumnBuilder.cs" />
|
||||
|
||||
@@ -26,24 +26,19 @@ namespace Umbraco.Tests.Migrations
|
||||
[Test]
|
||||
public void Can_Find_Migrations_With_Target_Version_Six()
|
||||
{
|
||||
var migrationResolver = new MigrationResolver(
|
||||
Container,
|
||||
Logger,
|
||||
() => new List<Type>
|
||||
{
|
||||
typeof (AlterUserTableMigrationStub),
|
||||
typeof(Dummy),
|
||||
typeof (SixZeroMigration1),
|
||||
typeof (SixZeroMigration2),
|
||||
typeof (FourElevenMigration),
|
||||
typeof (FiveZeroMigration)
|
||||
});
|
||||
var builder = new MigrationCollectionBuilder(Container)
|
||||
.Add<AlterUserTableMigrationStub>()
|
||||
.Add<Dummy>()
|
||||
.Add<SixZeroMigration1>()
|
||||
.Add<SixZeroMigration2>()
|
||||
.Add<FourElevenMigration>()
|
||||
.Add<FiveZeroMigration>();
|
||||
|
||||
var database = TestObjects.GetUmbracoSqlServerDatabase(Mock.Of<ILogger>());
|
||||
|
||||
var context = new MigrationContext(database, Logger);
|
||||
|
||||
var foundMigrations = migrationResolver.GetMigrations(context);
|
||||
var foundMigrations = builder.CreateCollection(context);
|
||||
var targetVersion = new Version("6.0.0");
|
||||
var list = new List<IMigration>();
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Umbraco.Tests.Migrations
|
||||
|
||||
//Setup the MigrationRunner
|
||||
var migrationRunner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
logger,
|
||||
new SemVersion(7, 5, 0),
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Tests.Migrations
|
||||
public void Executes_Only_One_Migration_For_Spanning_Multiple_Targets()
|
||||
{
|
||||
var runner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
_logger, new SemVersion(4 /*, 0, 0*/), new SemVersion(6 /*, 0, 0*/), "Test");
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Umbraco.Tests.Migrations
|
||||
public void Executes_Migration_For_Spanning_One_Target_1()
|
||||
{
|
||||
var runner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
_logger, new SemVersion(4 /*, 0, 0*/), new SemVersion(5 /*, 0, 0*/), "Test");
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Tests.Migrations
|
||||
public void Executes_Migration_For_Spanning_One_Target_2()
|
||||
{
|
||||
var runner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
_logger, new SemVersion(5, 0, 1), new SemVersion(6 /*, 0, 0*/), "Test");
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
/// <summary>Regular expression that finds multiline block comments.</summary>
|
||||
private static readonly Regex FindComments = new Regex(@"\/\*.*?\*\/", RegexOptions.Singleline | RegexOptions.Compiled);
|
||||
|
||||
internal MigrationResolver MigrationResolver { get; private set; }
|
||||
|
||||
[SetUp]
|
||||
public virtual void Initialize()
|
||||
{
|
||||
@@ -60,7 +58,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
|
||||
//Setup the MigrationRunner
|
||||
var migrationRunner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
logger,
|
||||
configuredVersion,
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Umbraco.Tests.Migrations.Upgrades
|
||||
//Setup the MigrationRunner
|
||||
var migrationContext = new MigrationContext(db, Mock.Of<ILogger>());
|
||||
var migrationRunner = new MigrationRunner(
|
||||
Mock.Of<IMigrationResolver>(),
|
||||
Mock.Of<IMigrationCollectionBuilder>(),
|
||||
Mock.Of<IMigrationEntryService>(),
|
||||
Mock.Of<ILogger>(), configuredVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Tests.Persistence.Migrations
|
||||
|
||||
var db = TestObjects.GetUmbracoSqlCeDatabase(logger);
|
||||
var migrationContext = new MigrationContext(db, logger);
|
||||
var runner1 = new MigrationRunner(Mock.Of<IMigrationResolver>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test1",
|
||||
var runner1 = new MigrationRunner(Mock.Of<IMigrationCollectionBuilder>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test1",
|
||||
new IMigration[] { Mock.Of<IMigration>() });
|
||||
var result1 = runner1.Execute(migrationContext /*, false*/);
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
@@ -58,13 +58,13 @@ namespace Umbraco.Tests.Persistence.Migrations
|
||||
|
||||
var db = TestObjects.GetUmbracoSqlCeDatabase(logger);
|
||||
var migrationContext = new MigrationContext(db, logger);
|
||||
var runner1 = new MigrationRunner(Mock.Of<IMigrationResolver>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test1",
|
||||
var runner1 = new MigrationRunner(Mock.Of<IMigrationCollectionBuilder>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test1",
|
||||
new IMigration[] { Mock.Of<IMigration>()});
|
||||
var result1 = runner1.Execute(migrationContext /*, false*/);
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
Assert.AreEqual(0, changed2.CountExecuted);
|
||||
|
||||
var runner2 = new MigrationRunner(Mock.Of<IMigrationResolver>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test2",
|
||||
var runner2 = new MigrationRunner(Mock.Of<IMigrationCollectionBuilder>(), Mock.Of<IMigrationEntryService>(), logger, new SemVersion(1), new SemVersion(2), "Test2",
|
||||
new IMigration[] { Mock.Of<IMigration>() });
|
||||
var result2 = runner2.Execute(migrationContext /*, false*/);
|
||||
Assert.AreEqual(1, changed1.CountExecuted);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using LightInject;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Web.HealthCheck;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
@@ -125,6 +126,9 @@ namespace Umbraco.Web
|
||||
public static ActionCollection Actions
|
||||
=> Container.GetInstance<ActionCollection>();
|
||||
|
||||
public static MigrationCollectionBuilder MigrationCollectionBuilder
|
||||
=> Container.GetInstance<MigrationCollectionBuilder>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Core Getters
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Web.Install.InstallSteps
|
||||
|
||||
var result = _applicationContext.DatabaseContext.UpgradeSchemaAndData(
|
||||
_applicationContext.Services.MigrationEntryService,
|
||||
MigrationResolver.Current);
|
||||
Current.MigrationCollectionBuilder);
|
||||
|
||||
if (result.Success == false)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user