protected virtual string GetDirectory( [NotNull] string projectDir, [CanBeNull] string siblingFileName, [NotNull] string subnamespace) { Check.NotEmpty(projectDir, nameof(projectDir)); Check.NotNull(subnamespace, nameof(subnamespace)); var defaultDirectory = Path.Combine(projectDir, Path.Combine(subnamespace.Split('.'))); if (siblingFileName != null) { var siblingPath = TryGetProjectFile(projectDir, siblingFileName); if (siblingPath != null) { var lastDirectory = Path.GetDirectoryName(siblingPath); if (!defaultDirectory.Equals(lastDirectory, StringComparison.OrdinalIgnoreCase)) { _logger.Value.LogDebug(DesignCoreStrings.ReusingDirectory(siblingFileName)); return(lastDirectory); } } } return(defaultDirectory); }
public virtual MigrationFiles Save( [NotNull] string projectDir, [NotNull] ScaffoldedMigration migration, [CanBeNull] string outputDir) { Check.NotEmpty(projectDir, nameof(projectDir)); Check.NotNull(migration, nameof(migration)); var lastMigrationFileName = migration.PreviousMigrationId + migration.FileExtension; var migrationDirectory = outputDir ?? GetDirectory(projectDir, lastMigrationFileName, migration.MigrationSubNamespace); var migrationFile = Path.Combine(migrationDirectory, migration.MigrationId + migration.FileExtension); var migrationMetadataFile = Path.Combine(migrationDirectory, migration.MigrationId + ".Designer" + migration.FileExtension); var modelSnapshotFileName = migration.SnapshotName + migration.FileExtension; var modelSnapshotDirectory = outputDir ?? GetDirectory(projectDir, modelSnapshotFileName, migration.SnapshotSubnamespace); var modelSnapshotFile = Path.Combine(modelSnapshotDirectory, modelSnapshotFileName); _logger.Value.LogDebug(DesignCoreStrings.WritingMigration(migrationFile)); Directory.CreateDirectory(migrationDirectory); File.WriteAllText(migrationFile, migration.MigrationCode, Encoding.UTF8); File.WriteAllText(migrationMetadataFile, migration.MetadataCode, Encoding.UTF8); _logger.Value.LogDebug(DesignCoreStrings.WritingSnapshot(modelSnapshotFile)); Directory.CreateDirectory(modelSnapshotDirectory); File.WriteAllText(modelSnapshotFile, migration.SnapshotCode, Encoding.UTF8); return(new MigrationFiles { MigrationFile = migrationFile, MetadataFile = migrationMetadataFile, SnapshotFile = modelSnapshotFile }); }
protected virtual void Generate([NotNull] MigrationOperation operation, [NotNull] IndentedStringBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); throw new InvalidOperationException(DesignCoreStrings.UnknownOperation(operation.GetType())); }
public void UnknownLiteral_throws_when_unknown() { var ex = Assert.Throws <InvalidOperationException>( () => new CSharpHelper().UnknownLiteral(new object())); Assert.Equal(DesignCoreStrings.UnknownLiteral(typeof(object)), ex.Message); }
public virtual string UnknownLiteral([CanBeNull] object value) { if (value == null) { return("null"); } var type = value.GetType().UnwrapNullableType(); Func <CSharpHelper, object, string> literalFunc; if (_literalFuncs.TryGetValue(type, out literalFunc)) { return(literalFunc(this, value)); } var enumValue = value as Enum; if (enumValue != null) { return(Literal(enumValue)); } throw new InvalidOperationException(DesignCoreStrings.UnknownLiteral(value.GetType())); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual void CheckValidity() { if (string.IsNullOrEmpty(ConnectionString)) { throw new ArgumentException(DesignCoreStrings.ConnectionStringRequired); } if (string.IsNullOrEmpty(ProjectPath)) { throw new ArgumentException(DesignCoreStrings.ProjectPathRequired); } if (!string.IsNullOrWhiteSpace(ContextClassName) && (!CSharpUtilities.Instance.IsValidIdentifier(ContextClassName) || CSharpUtilities.Instance.IsCSharpKeyword(ContextClassName))) { throw new ArgumentException( DesignCoreStrings.ContextClassNotValidCSharpIdentifier(ContextClassName)); } if (string.IsNullOrEmpty(ProjectRootNamespace)) { throw new ArgumentException(DesignCoreStrings.RootNamespaceRequired); } }
private object Invoke(Type type, string[] methodNames, IServiceCollection services) { if (type == null) { return(null); } MethodInfo method = null; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < methodNames.Length; i++) { method = type.GetTypeInfo().GetDeclaredMethod(methodNames[i]); if (method != null) { break; } } if (method == null) { return(null); } try { var instance = !method.IsStatic ? ActivatorUtilities.GetServiceOrCreateInstance(GetHostServices(), type) : null; var parameters = method.GetParameters(); var arguments = new object[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { var parameterType = parameters[i].ParameterType; arguments[i] = parameterType == typeof(IServiceCollection) ? services : ActivatorUtilities.GetServiceOrCreateInstance(GetHostServices(), parameterType); } return(method.Invoke(instance, arguments)); } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ex.InnerException; } _logger.Value.LogWarning( DesignCoreStrings.InvokeStartupMethodFailed(method.Name, type.DisplayName(), ex.Message)); _logger.Value.LogDebug(ex.ToString()); return(null); } }
private Type GetProviderDesignTimeServices(string provider, bool throwOnError) { Assembly providerAssembly; try { providerAssembly = _assemblyLoader.Load(provider); } catch (Exception ex) { if (!throwOnError) { return(null); } throw new OperationException(DesignCoreStrings.CannotFindRuntimeProviderAssembly(provider), ex); } var providerServicesAttribute = providerAssembly.GetCustomAttribute <DesignTimeProviderServicesAttribute>(); if (providerServicesAttribute == null) { if (!throwOnError) { return(null); } throw new InvalidOperationException( DesignCoreStrings.CannotFindDesignTimeProviderAssemblyAttribute( nameof(DesignTimeProviderServicesAttribute), provider)); } Assembly designTimeProviderAssembly; try { designTimeProviderAssembly = _assemblyLoader.Load(providerServicesAttribute.AssemblyName); } catch (Exception ex) when(ex is FileNotFoundException || ex is FileLoadException || ex is BadImageFormatException) { if (!throwOnError) { return(null); } throw new OperationException( DesignCoreStrings.CannotFindDesignTimeProviderAssembly(providerServicesAttribute.PackageName), ex); } return(designTimeProviderAssembly.GetType( providerServicesAttribute.TypeName, throwOnError: true, ignoreCase: false)); }
public void Throws_for_no_parameterless_constructor() { using (var directory = new TempDirectory()) { var targetDir = directory.Path; var source = new BuildSource { TargetDir = targetDir, References = { BuildReference.ByName("System.Diagnostics.DiagnosticSource", copyLocal: true), BuildReference.ByName("System.Interactive.Async", copyLocal: true), BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Tools", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Design.Core", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Caching.Memory", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.DependencyInjection", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Logging", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Options", copyLocal: true), BuildReference.ByName("Remotion.Linq", copyLocal: true) }, Sources = { @" using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; namespace MyProject { internal class MyContext : DbContext { public MyContext(DbContextOptions<MyContext> options) :base(options) {} } }" } }; var build = source.Build(); using (var executor = new AppDomainOperationExecutor(targetDir, build.TargetName, targetDir, targetDir, "MyProject")) { var ex = Assert.Throws <OperationException>( () => executor.GetMigrations("MyContext")); Assert.Equal( DesignCoreStrings.NoParameterlessConstructor("MyContext"), ex.Message); } } }
private DbContext CreateContext(Func <DbContext> factory) { var context = factory(); _logger.Value.LogDebug(DesignCoreStrings.LogUseContext(context.GetType().ShortDisplayName())); var loggerFactory = context.GetService <ILoggerFactory>(); loggerFactory.AddProvider(_loggerProvider); return(context); }
private KeyValuePair <Type, Func <DbContext> > FindContextType(string name) { var types = FindContextTypes(); if (string.IsNullOrEmpty(name)) { if (types.Count == 0) { throw new OperationException(DesignCoreStrings.NoContext(_assembly.GetName().Name)); } if (types.Count == 1) { return(types.First()); } throw new OperationException(DesignCoreStrings.MultipleContexts); } var candidates = FilterTypes(types, name, ignoreCase: true); if (candidates.Count == 0) { throw new OperationException(DesignCoreStrings.NoContextWithName(name)); } if (candidates.Count == 1) { return(candidates.First()); } // Disambiguate using case candidates = FilterTypes(candidates, name); if (candidates.Count == 0) { throw new OperationException(DesignCoreStrings.MultipleContextsWithName(name)); } if (candidates.Count == 1) { return(candidates.First()); } // Allow selecting types in the default namespace candidates = candidates.Where(t => t.Key.Namespace == null).ToDictionary(t => t.Key, t => t.Value); if (candidates.Count == 0) { throw new OperationException(DesignCoreStrings.MultipleContextsWithQualifiedName(name)); } Debug.Assert(candidates.Count == 1, "candidates.Count is not 1."); return(candidates.First()); }
public void Throws_exceptions_for_incorrect_configuration() { var configuration = new ReverseEngineeringConfiguration { ConnectionString = null, ProjectPath = null, OutputPath = null }; Assert.Equal(DesignCoreStrings.ConnectionStringRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ConnectionString = "NonEmptyConnectionString"; Assert.Equal(DesignCoreStrings.ProjectPathRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ProjectPath = "NonEmptyProjectPath"; Assert.Equal(DesignCoreStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = @"Invalid!CSharp*Class&Name"; Assert.Equal(DesignCoreStrings.ContextClassNotValidCSharpIdentifier(@"Invalid!CSharp*Class&Name"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "1CSharpClassNameCannotStartWithNumber"; Assert.Equal(DesignCoreStrings.ContextClassNotValidCSharpIdentifier("1CSharpClassNameCannotStartWithNumber"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "volatile"; // cannot be C# keyword Assert.Equal(DesignCoreStrings.ContextClassNotValidCSharpIdentifier("volatile"), Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.ContextClassName = "GoodClassName"; configuration.OutputPath = @"\AnAbsolutePath"; Assert.Equal(DesignCoreStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); configuration.OutputPath = @"A\Relative\Path"; Assert.Equal(DesignCoreStrings.RootNamespaceRequired, Assert.Throws <ArgumentException>( () => configuration.CheckValidity()).Message); }
protected virtual string GetNamespace([CanBeNull] Type siblingType, [NotNull] string defaultNamespace) { if (siblingType != null) { var lastNamespace = siblingType.Namespace; if (lastNamespace != defaultNamespace) { _logger.Value.LogDebug(DesignCoreStrings.ReusingNamespace(siblingType.ShortDisplayName())); return(lastNamespace); } } return(defaultNamespace); }
private static void SerializeObject(object obj, IndentedStringBuilder sb) { if (obj == null) { sb.Append("null"); return; } if (obj is string) { SerializeString(obj as string, sb); return; } if (obj is bool) { sb.Append(((bool)obj) ? "true" : "false"); return; } if (obj is short || obj is ushort || obj is int || obj is uint || obj is long || obj is ulong || obj is decimal || obj is float || obj is double) { sb.Append(obj); return; } if (obj is IEnumerable) { SerializeEnumerable(obj as IEnumerable, sb); return; } if (obj.GetType().GetTypeInfo().IsClass) { SerializeClass(obj, sb); return; } throw new ArgumentException(DesignCoreStrings.CouldNotSerialize(obj, obj.GetType().FullName)); }
public void Invoke_warns_on_error() { var log = new List <Tuple <LogLevel, string> >(); var startup = new StartupInvoker( new LazyRef <ILogger>(() => new ListLoggerFactory(log).CreateLogger("Test")), MockAssembly.Create(typeof(BadStartup)), /*environment:*/ null, "Irrelevant"); var services = startup.ConfigureServices(); Assert.NotNull(services); Assert.Equal( DesignCoreStrings.InvokeStartupMethodFailed( "ConfigureServices", nameof(BadStartup), "Something went wrong."), log[0].Item2); }
private void EnsureServices(IServiceProvider services) { var providerServices = services.GetRequiredService <IDatabaseProviderServices>(); if (!(providerServices is IRelationalDatabaseProviderServices)) { throw new OperationException(DesignCoreStrings.NonRelationalProvider(providerServices.InvariantName)); } var assemblyName = _assembly.GetName(); var options = services.GetRequiredService <IDbContextOptions>(); var contextType = services.GetRequiredService <ICurrentDbContext>().Context.GetType(); var migrationsAssemblyName = RelationalOptionsExtension.Extract(options).MigrationsAssembly ?? contextType.GetTypeInfo().Assembly.GetName().Name; if (assemblyName.Name != migrationsAssemblyName && assemblyName.FullName != migrationsAssemblyName) { throw new OperationException( DesignCoreStrings.MigrationsAssemblyMismatch(assemblyName.Name, migrationsAssemblyName)); } }
protected override void Generate([NotNull] MigrationOperation operation, [NotNull] IndentedStringBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); var asCreateExtensionOperation = operation as NpgsqlCreatePostgresExtensionOperation; if (asCreateExtensionOperation != null) { Generate(asCreateExtensionOperation, builder); return; } var asDropExtensionOperation = operation as NpgsqlDropPostgresExtensionOperation; if (asDropExtensionOperation != null) { Generate(asDropExtensionOperation, builder); return; } throw new InvalidOperationException(DesignCoreStrings.UnknownOperation(operation.GetType())); }
public virtual void DropDatabase([CanBeNull] string contextType, [NotNull] Func <string, string, bool> confirmCheck) { using (var context = CreateContext(contextType)) { var connection = context.Database.GetDbConnection(); if (confirmCheck(connection.Database, connection.DataSource)) { _logger.Value.LogInformation(DesignCoreStrings.LogDroppingDatabase(connection.Database)); if (context.Database.EnsureDeleted()) { _logger.Value.LogInformation(DesignCoreStrings.LogDatabaseDropped(connection.Database)); } else { _logger.Value.LogInformation(DesignCoreStrings.LogNotExistDatabase(connection.Database)); } } else { _logger.Value.LogInformation(DesignCoreStrings.Cancelled); } } }
public virtual ScaffoldedMigration ScaffoldMigration( [NotNull] string migrationName, [NotNull] string rootNamespace, [CanBeNull] string subNamespace = null) { Check.NotEmpty(migrationName, nameof(migrationName)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); if (_migrationsAssembly.FindMigrationId(migrationName) != null) { throw new InvalidOperationException(DesignCoreStrings.DuplicateMigrationName(migrationName)); } var subNamespaceDefaulted = false; if (string.IsNullOrEmpty(subNamespace)) { subNamespaceDefaulted = true; subNamespace = "Migrations"; } var lastMigration = _migrationsAssembly.Migrations.LastOrDefault(); var migrationNamespace = rootNamespace + "." + subNamespace; if (subNamespaceDefaulted) { migrationNamespace = GetNamespace(lastMigration.Value?.AsType(), migrationNamespace); } var sanitizedContextName = _contextType.Name; var genericMarkIndex = sanitizedContextName.IndexOf('`'); if (genericMarkIndex != -1) { sanitizedContextName = sanitizedContextName.Substring(0, genericMarkIndex); } if (ContainsForeignMigrations(migrationNamespace)) { if (subNamespaceDefaulted) { var builder = new StringBuilder() .Append(rootNamespace) .Append(".Migrations."); if (sanitizedContextName.EndsWith("Context", StringComparison.Ordinal)) { builder.Append(sanitizedContextName.Substring(0, sanitizedContextName.Length - 7)); } else { builder .Append(sanitizedContextName) .Append("Migrations"); } migrationNamespace = builder.ToString(); } else { _logger.Value.LogWarning(DesignCoreStrings.ForeignMigrations(migrationNamespace)); } } var modelSnapshot = _migrationsAssembly.ModelSnapshot; var lastModel = modelSnapshot?.Model; var upOperations = _modelDiffer.GetDifferences(lastModel, _model); var downOperations = upOperations.Any() ? _modelDiffer.GetDifferences(_model, lastModel) : new List <MigrationOperation>(); var migrationId = _idGenerator.GenerateId(migrationName); var modelSnapshotNamespace = GetNamespace(modelSnapshot?.GetType(), migrationNamespace); var modelSnapshotName = sanitizedContextName + "ModelSnapshot"; if (modelSnapshot != null) { var lastModelSnapshotName = modelSnapshot.GetType().Name; if (lastModelSnapshotName != modelSnapshotName) { _logger.Value.LogDebug(DesignCoreStrings.ReusingSnapshotName(lastModelSnapshotName)); modelSnapshotName = lastModelSnapshotName; } } if (upOperations.Any(o => o.IsDestructiveChange)) { _logger.Value.LogWarning(DesignCoreStrings.DestructiveOperation); } var migrationCode = _migrationCodeGenerator.GenerateMigration( migrationNamespace, migrationName, upOperations, downOperations); var migrationMetadataCode = _migrationCodeGenerator.GenerateMetadata( migrationNamespace, _contextType, migrationName, migrationId, _model); var modelSnapshotCode = _migrationCodeGenerator.GenerateSnapshot( modelSnapshotNamespace, _contextType, modelSnapshotName, _model); return(new ScaffoldedMigration( _migrationCodeGenerator.FileExtension, lastMigration.Key, migrationCode, migrationId, migrationMetadataCode, GetSubNamespace(rootNamespace, migrationNamespace), modelSnapshotCode, modelSnapshotName, GetSubNamespace(rootNamespace, modelSnapshotNamespace))); }
public void GetMigrations_throws_when_target_and_migrations_assemblies_mismatch() { using (var directory = new TempDirectory()) { var targetDir = directory.Path; var source = new BuildSource { TargetDir = targetDir, References = { BuildReference.ByName("System.Diagnostics.DiagnosticSource", copyLocal: true), BuildReference.ByName("System.Interactive.Async", copyLocal: true), BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Tools", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Design.Core", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", copyLocal: true), BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Caching.Memory", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.DependencyInjection", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Logging", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", copyLocal: true), BuildReference.ByName("Microsoft.Extensions.Options", copyLocal: true), BuildReference.ByName("Remotion.Linq", copyLocal: true) }, Sources = { @" using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; namespace MyProject { internal class MyContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseSqlServer( ""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MyProject.MyContext;Integrated Security=True"", b => b.MigrationsAssembly(""UnknownAssembly"")); } } namespace Migrations { [DbContext(typeof(MyContext))] [Migration(""20151215152142_MyMigration"")] public class MyMigration : Migration { protected override void Up(MigrationBuilder migrationBuilder) { } } } }" } }; var build = source.Build(); using (var executor = new AppDomainOperationExecutor(targetDir, build.TargetName, targetDir, targetDir, "MyProject")) { var ex = Assert.Throws <OperationException>( () => executor.GetMigrations("MyContext")); Assert.Equal( DesignCoreStrings.MigrationsAssemblyMismatch(build.TargetName, "UnknownAssembly"), ex.Message); } } }
public OperationExecutor([NotNull] object logHandler, [NotNull] IDictionary args, [NotNull] AssemblyLoader assemblyLoader) { Check.NotNull(logHandler, nameof(logHandler)); Check.NotNull(args, nameof(args)); Check.NotNull(assemblyLoader, nameof(assemblyLoader)); var unwrappedLogHandler = ForwardingProxy.Unwrap <IOperationLogHandler>(logHandler); var loggerProvider = new LoggerProvider(name => new CommandLoggerAdapter(name, unwrappedLogHandler)); var targetName = (string)args["targetName"]; var startupTargetName = (string)args["startupTargetName"]; var environment = (string)args["environment"]; _projectDir = (string)args["projectDir"]; var contentRootPath = (string)args["contentRootPath"]; var rootNamespace = (string)args["rootNamespace"]; // NOTE: LazyRef is used so any exceptions get passed to the resultHandler var startupAssembly = new LazyRef <Assembly>( () => assemblyLoader.Load(startupTargetName)); var assembly = new LazyRef <Assembly>( () => { try { return(assemblyLoader.Load(targetName)); } catch (Exception ex) { throw new OperationException( DesignCoreStrings.UnreferencedAssembly(targetName, startupTargetName), ex); } }); _contextOperations = new LazyRef <DbContextOperations>( () => new DbContextOperations( loggerProvider, assembly.Value, startupAssembly.Value, environment, contentRootPath)); _databaseOperations = new LazyRef <DatabaseOperations>( () => new DatabaseOperations( loggerProvider, assemblyLoader, startupAssembly.Value, environment, _projectDir, contentRootPath, rootNamespace)); _migrationsOperations = new LazyRef <MigrationsOperations>( () => new MigrationsOperations( loggerProvider, assembly.Value, assemblyLoader, startupAssembly.Value, environment, _projectDir, contentRootPath, rootNamespace)); }
// TODO: DRY (file names) public virtual MigrationFiles RemoveMigration([NotNull] string projectDir, [NotNull] string rootNamespace, bool force) { Check.NotEmpty(projectDir, nameof(projectDir)); Check.NotEmpty(rootNamespace, nameof(rootNamespace)); var files = new MigrationFiles(); var modelSnapshot = _migrationsAssembly.ModelSnapshot; if (modelSnapshot == null) { throw new InvalidOperationException(DesignCoreStrings.NoSnapshot); } var language = _migrationCodeGenerator.FileExtension; IModel model = null; var migrations = _migrationsAssembly.Migrations .Select(m => _migrationsAssembly.CreateMigration(m.Value, _activeProvider)) .ToList(); if (migrations.Count != 0) { var migration = migrations[migrations.Count - 1]; model = migration.TargetModel; if (!_modelDiffer.HasDifferences(model, modelSnapshot.Model)) { if (force) { _logger.Value.LogWarning(DesignCoreStrings.ForceRemoveMigration(migration.GetId())); } else if (_historyRepository.GetAppliedMigrations().Any( e => e.MigrationId.Equals(migration.GetId(), StringComparison.OrdinalIgnoreCase))) { throw new InvalidOperationException(DesignCoreStrings.UnapplyMigration(migration.GetId())); } var migrationFileName = migration.GetId() + language; var migrationFile = TryGetProjectFile(projectDir, migrationFileName); if (migrationFile != null) { _logger.Value.LogInformation(DesignCoreStrings.RemovingMigration(migration.GetId())); File.Delete(migrationFile); files.MigrationFile = migrationFile; } else { _logger.Value.LogWarning( DesignCoreStrings.NoMigrationFile(migrationFileName, migration.GetType().ShortDisplayName())); } var migrationMetadataFileName = migration.GetId() + ".Designer" + language; var migrationMetadataFile = TryGetProjectFile(projectDir, migrationMetadataFileName); if (migrationMetadataFile != null) { File.Delete(migrationMetadataFile); files.MetadataFile = migrationMetadataFile; } else { _logger.Value.LogDebug(DesignCoreStrings.NoMigrationMetadataFile(migrationMetadataFileName)); } model = migrations.Count > 1 ? migrations[migrations.Count - 2].TargetModel : null; } else { _logger.Value.LogDebug(DesignCoreStrings.ManuallyDeleted); } } var modelSnapshotName = modelSnapshot.GetType().Name; var modelSnapshotFileName = modelSnapshotName + language; var modelSnapshotFile = TryGetProjectFile(projectDir, modelSnapshotFileName); if (model == null) { if (modelSnapshotFile != null) { _logger.Value.LogInformation(DesignCoreStrings.RemovingSnapshot); File.Delete(modelSnapshotFile); files.SnapshotFile = modelSnapshotFile; } else { _logger.Value.LogWarning( DesignCoreStrings.NoSnapshotFile(modelSnapshotFileName, modelSnapshot.GetType().ShortDisplayName())); } } else { var modelSnapshotNamespace = modelSnapshot.GetType().Namespace; Debug.Assert(!string.IsNullOrEmpty(modelSnapshotNamespace)); var modelSnapshotCode = _migrationCodeGenerator.GenerateSnapshot( modelSnapshotNamespace, _contextType, modelSnapshotName, model); if (modelSnapshotFile == null) { modelSnapshotFile = Path.Combine( GetDirectory(projectDir, null, GetSubNamespace(rootNamespace, modelSnapshotNamespace)), modelSnapshotFileName); } _logger.Value.LogInformation(DesignCoreStrings.RevertingSnapshot); File.WriteAllText(modelSnapshotFile, modelSnapshotCode, Encoding.UTF8); } return(files); }
private IDictionary <Type, Func <DbContext> > FindContextTypes() { _logger.Value.LogDebug(DesignCoreStrings.LogFindingContexts); var contexts = new Dictionary <Type, Func <DbContext> >(); // Look for IDbContextFactory implementations var contextFactories = _startupAssembly.GetConstructableTypes() .Where(t => typeof(IDbContextFactory <DbContext>).GetTypeInfo().IsAssignableFrom(t)); foreach (var factory in contextFactories) { var manufacturedContexts = from i in factory.ImplementedInterfaces where i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == typeof(IDbContextFactory <>) select i.GenericTypeArguments[0]; foreach (var context in manufacturedContexts) { contexts.Add( context, () => ((IDbContextFactory <DbContext>)Activator.CreateInstance(factory.AsType())).Create( CreateFactoryOptions())); } } // Look for DbContext classes registered in the service provider var registeredContexts = _runtimeServices.GetServices <DbContextOptions>() .Select(o => o.ContextType); foreach (var context in registeredContexts.Where(c => !contexts.ContainsKey(c))) { contexts.Add( context, FindContextFactory(context) ?? (() => (DbContext)_runtimeServices.GetRequiredService(context))); } // Look for DbContext classes in assemblies var types = _startupAssembly.GetConstructableTypes() .Concat(_assembly.GetConstructableTypes()) .Select(i => i.AsType()) .ToList(); var contextTypes = types.Where(t => typeof(DbContext).IsAssignableFrom(t)) .Concat( types.Where(t => typeof(Migration).IsAssignableFrom(t)) .Select(t => t.GetTypeInfo().GetCustomAttribute <DbContextAttribute>()?.ContextType) .Where(t => t != null)) .Distinct(); foreach (var context in contextTypes.Where(c => !contexts.ContainsKey(c))) { contexts.Add( context, FindContextFactory(context) ?? (Func <DbContext>)(() => { try { return((DbContext)Activator.CreateInstance(context)); } catch (MissingMethodException ex) { throw new OperationException(DesignCoreStrings.NoParameterlessConstructor(context.Name), ex); } })); } return(contexts); }