public static ServiceProvider Build(ReverseEngineerCommandOptions options)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
            .AddSingleton <ICSharpEntityTypeGenerator, CommentCSharpEntityTypeGenerator>()
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            if (options.CustomReplacers != null)
            {
                serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(options.CustomReplacers));
            }

            if (options.UseHandleBars)
            {
                //TODO Consider being selective based on SelectedToBeGenerated
                serviceCollection.AddHandlebarsScaffolding(hbOptions =>
                {
                    hbOptions.ReverseEngineerOptions = ReverseEngineerOptions.DbContextAndEntities;
                    hbOptions.LanguageOptions        = (LanguageOptions)options.SelectedHandlebarsLanguage;
                });
                serviceCollection.AddSingleton <ITemplateFileService>(provider => new CustomTemplateFileService(options.ProjectPath));
            }

            if (options.UseLegacyPluralizer)
            {
                serviceCollection.AddSingleton <IPluralizer, LegacyPluralizer>();
            }

            // Add database provider services
            switch (options.DatabaseType)
            {
            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);

                if (!string.IsNullOrEmpty(options.Dacpac))
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                }

                if (options.UseSpatial)
                {
                    var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                if (string.IsNullOrEmpty(options.Dacpac))
                {
                    serviceCollection.AddSqlServerStoredProcedureDesignTimeServices();
                }

                var builder = new SqlConnectionStringBuilder(options.ConnectionString)
                {
                    CommandTimeout = 300
                };
                options.ConnectionString = builder.ConnectionString;

                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);

                if (options.UseNodaTime)
                {
                    var nodaTime = new NpgsqlNodaTimeDesignTimeServices();
                    nodaTime.ConfigureDesignTimeServices(serviceCollection);
                }

                if (options.UseSpatial)
                {
                    var spatial = new NpgsqlNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.Mysql:
                var mysqlProvider = new MySqlDesignTimeServices();
                mysqlProvider.ConfigureDesignTimeServices(serviceCollection);

                if (options.UseSpatial)
                {
                    var spatial = new MySqlNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(serviceCollection.BuildServiceProvider());
        }
        public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions reverseEngineerOptions)
        {
            var errors   = new List <string>();
            var warnings = new List <string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));

            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddScaffolding(reporter)
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            if (reverseEngineerOptions.UseHandleBars)
            {
                serviceCollection.AddHandlebarsScaffolding(reverseEngineerOptions.ProjectPath);
            }

            if (reverseEngineerOptions.UseInflector)
            {
                serviceCollection.AddSingleton <IPluralizer, InflectorPluralizer>();
            }

            // Add database provider services
            switch (reverseEngineerOptions.DatabaseType)
            {
            case DatabaseType.SQLCE35:
                throw new NotImplementedException();

            case DatabaseType.SQLCE40:
                var sqlCeProvider = new SqlCeDesignTimeServices();
                sqlCeProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                serviceCollection.AddSingleton <IDatabaseModelFactory, CustomSqliteDatabaseModelFactory>();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var serviceProvider = serviceCollection.BuildServiceProvider();
            var generator       = serviceProvider.GetService <IModelScaffolder>();

            var filePaths = generator.Generate(
                reverseEngineerOptions.ConnectionString,
                reverseEngineerOptions.Tables,
                new List <string>(),
                reverseEngineerOptions.ProjectPath,
                reverseEngineerOptions.OutputPath,
                reverseEngineerOptions.ProjectRootNamespace,
                reverseEngineerOptions.ContextClassName,
                !reverseEngineerOptions.UseFluentApiOnly,
                overwriteFiles: true,
                useDatabaseNames: reverseEngineerOptions.UseDatabaseNames);

            // Explanation: Use table and column names directly from the database.

            foreach (var file in filePaths.EntityTypeFiles)
            {
                PostProcess(file, reverseEngineerOptions.IdReplace);
            }
            PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace);

            if (!reverseEngineerOptions.IncludeConnectionString)
            {
                PostProcessContext(filePaths.ContextFile);
            }

            var result = new EfCoreReverseEngineerResult
            {
                EntityErrors        = errors,
                EntityWarnings      = warnings,
                EntityTypeFilePaths = filePaths.EntityTypeFiles,
                ContextFilePath     = filePaths.ContextFile,
            };

            return(result);
        }
示例#3
0
        public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions reverseEngineerOptions)
        {
            var errors   = new List <string>();
            var warnings = new List <string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));

            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            //TODO await update to 2.1
            //if (reverseEngineerOptions.UseHandleBars)
            //{
            //    serviceCollection.AddHandlebarsScaffolding(reverseEngineerOptions.ProjectPath);
            //}

            if (reverseEngineerOptions.UseInflector)
            {
                serviceCollection.AddSingleton <IPluralizer, InflectorPluralizer>();
            }

            // Add database provider services
            switch (reverseEngineerOptions.DatabaseType)
            {
            case DatabaseType.SQLCE35:
                throw new NotImplementedException();

            case DatabaseType.SQLCE40:
                var sqlCeProvider = new SqlCeDesignTimeServices();
                sqlCeProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);
                if (!string.IsNullOrEmpty(reverseEngineerOptions.Dacpac))
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                }
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                serviceCollection.AddSingleton <IDatabaseModelFactory, CustomSqliteDatabaseModelFactory>();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var serviceProvider = serviceCollection.BuildServiceProvider();
            var scaffolder      = serviceProvider.GetService <IReverseEngineerScaffolder>();

            var schemas = new List <string>();

            if (reverseEngineerOptions.DefaultDacpacSchema != null)
            {
                schemas.Add(reverseEngineerOptions.DefaultDacpacSchema);
            }

            var @namespace = reverseEngineerOptions.ProjectRootNamespace;

            var subNamespace = SubnamespaceFromOutputPath(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath);

            if (!string.IsNullOrEmpty(subNamespace))
            {
                @namespace += "." + subNamespace;
            }

            var scaffoldedModel = scaffolder.ScaffoldModel(
                reverseEngineerOptions.Dacpac != null
                        ? reverseEngineerOptions.Dacpac
                        : reverseEngineerOptions.ConnectionString,
                reverseEngineerOptions.Tables,
                schemas,
                @namespace,
                "C#",
                null,
                reverseEngineerOptions.ContextClassName,
                !reverseEngineerOptions.UseFluentApiOnly,
                useDatabaseNames: reverseEngineerOptions.UseDatabaseNames);

            var filePaths = scaffolder.Save(
                scaffoldedModel,
                Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath),
                overwriteFiles: true);

            foreach (var file in filePaths.AdditionalFiles)
            {
                PostProcess(file, reverseEngineerOptions.IdReplace);
            }
            PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace);

            PostProcessContext(filePaths.ContextFile, reverseEngineerOptions);

            var result = new EfCoreReverseEngineerResult
            {
                EntityErrors        = errors,
                EntityWarnings      = warnings,
                EntityTypeFilePaths = filePaths.AdditionalFiles,
                ContextFilePath     = filePaths.ContextFile,
            };

            return(result);
        }
        public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions reverseEngineerOptions)
        {
            var errors   = new List <string>();
            var warnings = new List <string>();
            var reporter = new OperationReporter(
                new OperationReportHandler(
                    m => errors.Add(m),
                    m => warnings.Add(m)));

            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            if (reverseEngineerOptions.UseHandleBars)
            {
                //TODO Consider being selective based on SelectedToBeGenerated
                serviceCollection.AddHandlebarsScaffolding();
                serviceCollection.AddSingleton <ITemplateFileService>(provider => new CustomTemplateFileService(reverseEngineerOptions.ProjectPath));
            }

            if (reverseEngineerOptions.CustomReplacers != null)
            {
                serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(reverseEngineerOptions.CustomReplacers));
            }

            if (reverseEngineerOptions.UseInflector)
            {
                serviceCollection.AddSingleton <IPluralizer, InflectorPluralizer>();
            }

            // Add database provider services
            switch (reverseEngineerOptions.DatabaseType)
            {
            case DatabaseType.SQLCE35:
                throw new NotImplementedException();

            case DatabaseType.SQLCE40:
                var sqlCeProvider = new SqlCeDesignTimeServices();
                sqlCeProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);

                var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                spatial.ConfigureDesignTimeServices(serviceCollection);

                if (!string.IsNullOrEmpty(reverseEngineerOptions.Dacpac))
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                }
                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.Mysql:
                var mysqlProvider = new MySqlDesignTimeServices();
                mysqlProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var serviceProvider = serviceCollection.BuildServiceProvider();
            var scaffolder      = serviceProvider.GetService <IReverseEngineerScaffolder>();

            var schemas = new List <string>();

            if (reverseEngineerOptions.DefaultDacpacSchema != null)
            {
                schemas.Add(reverseEngineerOptions.DefaultDacpacSchema);
            }

            var @namespace = reverseEngineerOptions.ProjectRootNamespace;

            if (!string.IsNullOrEmpty(reverseEngineerOptions.OutputPath))
            {
                @namespace += "." + reverseEngineerOptions.OutputPath.Replace(Path.DirectorySeparatorChar, '.').Replace(Path.AltDirectorySeparatorChar, '.');
            }
            var modelOptions = new ModelReverseEngineerOptions
            {
                UseDatabaseNames = reverseEngineerOptions.UseDatabaseNames
            };

            var codeOptions = new ModelCodeGenerationOptions
            {
                UseDataAnnotations = !reverseEngineerOptions.UseFluentApiOnly
            };

            var scaffoldedModel = scaffolder.ScaffoldModel(
                reverseEngineerOptions.Dacpac != null
                        ? reverseEngineerOptions.Dacpac
                        : reverseEngineerOptions.ConnectionString,
                reverseEngineerOptions.Tables.Select(m => m.Name).ToArray(),
                schemas,
                @namespace,
                "C#",
                null,
                reverseEngineerOptions.ContextClassName,
                modelOptions,
                codeOptions);

            var filePaths = scaffolder.Save(
                scaffoldedModel,
                Path.Combine(reverseEngineerOptions.ProjectPath, reverseEngineerOptions.OutputPath ?? string.Empty),
                overwriteFiles: true);

            PostProcessContext(filePaths.ContextFile, reverseEngineerOptions);

            foreach (var file in filePaths.AdditionalFiles)
            {
                PostProcess(file, reverseEngineerOptions.IdReplace);
            }
            PostProcess(filePaths.ContextFile, reverseEngineerOptions.IdReplace);

            var result = new EfCoreReverseEngineerResult
            {
                EntityErrors        = errors,
                EntityWarnings      = warnings,
                EntityTypeFilePaths = filePaths.AdditionalFiles,
                ContextFilePath     = filePaths.ContextFile,
            };

            return(result);
        }
示例#5
0
        public static ServiceProvider Build(ReverseEngineerCommandOptions options)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
            .AddSingleton <ICSharpEntityTypeGenerator, CommentCSharpEntityTypeGenerator>()
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            if (options.CustomReplacers != null)
            {
                serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(options.CustomReplacers));
            }

            if (options.UseInflector)
            {
                if (options.UseLegacyPluralizer)
                {
                    serviceCollection.AddSingleton <IPluralizer, LegacyPluralizer>();
                }
                else
                {
                    serviceCollection.AddSingleton <IPluralizer, HumanizerPluralizer>();
                }
            }

            // Add database provider services
            switch (options.DatabaseType)
            {
            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);

                if (!string.IsNullOrEmpty(options.Dacpac))
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                }
                else
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerFasterDatabaseModelFactory>();
                }

                if (options.UseSpatial)
                {
                    var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                if (string.IsNullOrEmpty(options.Dacpac) &&
                    options.UseStoredProcedures)
                {
                    serviceCollection.AddSqlServerStoredProcedureDesignTimeServices();
                }

                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);

                if (options.UseNodaTime)
                {
                    var nodaTime = new NpgsqlNodaTimeDesignTimeServices();
                    nodaTime.ConfigureDesignTimeServices(serviceCollection);
                }

                if (options.UseSpatial)
                {
                    var spatial = new NpgsqlNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(serviceCollection.BuildServiceProvider());
        }
        public static ServiceProvider Build(ReverseEngineerCommandOptions options)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
#if CORE50
            .AddSingleton <ICSharpEntityTypeGenerator>(provider =>
                                                       new CommentCSharpEntityTypeGenerator(
                                                           provider.GetService <IAnnotationCodeGenerator>(),
                                                           provider.GetService <ICSharpHelper>(),
                                                           options.UseNullableReferences,
                                                           options.UseNoConstructor))
#else
            .AddSingleton <ICSharpEntityTypeGenerator>(provider =>
                                                       new CommentCSharpEntityTypeGenerator(
                                                           provider.GetService <ICSharpHelper>(),
                                                           options.UseNullableReferences,
                                                           options.UseNoConstructor))
#endif
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>()
            .AddSingleton <IScaffoldingModelFactory>(provider =>
                                                     new ColumnRemovingScaffoldingModelFactory(
                                                         provider.GetService <IOperationReporter>(),
                                                         provider.GetService <ICandidateNamingService>(),
                                                         provider.GetService <IPluralizer>(),
                                                         provider.GetService <ICSharpUtilities>(),
                                                         provider.GetService <IScaffoldingTypeMapper>(),
                                                         provider.GetService <LoggingDefinitions>(),
                                                         options.Tables,
                                                         options.DatabaseType
                                                         ));

            if (options.CustomReplacers != null)
            {
                serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(options.CustomReplacers));
            }

            if (options.UseHandleBars)
            {
                serviceCollection.AddHandlebarsScaffolding(hbOptions =>
                {
                    hbOptions.ReverseEngineerOptions = ReverseEngineerOptions.DbContextAndEntities;
                    hbOptions.LanguageOptions        = (LanguageOptions)options.SelectedHandlebarsLanguage;
                });
                serviceCollection.AddSingleton <ITemplateFileService>(provider => new CustomTemplateFileService(options.ProjectPath));
            }

            if (options.UseInflector || options.UseLegacyPluralizer)
            {
                if (options.UseLegacyPluralizer)
                {
                    serviceCollection.AddSingleton <IPluralizer, LegacyPluralizer>();
                }
#if CORE50
#else
                else
                {
                    serviceCollection.AddSingleton <IPluralizer, HumanizerPluralizer>();
                }
#endif
            }

            // Add database provider services
            switch (options.DatabaseType)
            {
            case DatabaseType.Edmx:
                var edmxProvider = new SqlServerDesignTimeServices();
                edmxProvider.ConfigureDesignTimeServices(serviceCollection);

                serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerEdmxDatabaseModelFactory>();

                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);

                serviceCollection.AddSqlServerStoredProcedureDesignTimeServices();
                serviceCollection.AddSqlServerFunctionDesignTimeServices();

                if (options.UseSpatial)
                {
                    var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.SQLServerDacpac:
                var dacProvider = new SqlServerDesignTimeServices();
                dacProvider.ConfigureDesignTimeServices(serviceCollection);

                serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                serviceCollection.AddSqlServerDacpacStoredProcedureDesignTimeServices();

                if (options.UseSpatial)
                {
                    var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);

                if (options.UseNodaTime)
                {
                    var nodaTime = new NpgsqlNodaTimeDesignTimeServices();
                    nodaTime.ConfigureDesignTimeServices(serviceCollection);
                }

                if (options.UseSpatial)
                {
                    var spatial = new NpgsqlNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.Mysql:
                var mysqlProvider = new MySqlDesignTimeServices();
                mysqlProvider.ConfigureDesignTimeServices(serviceCollection);

                if (options.UseSpatial)
                {
                    var spatial = new MySqlNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.Oracle:
                var oracleProvider = new OracleDesignTimeServices();
                oracleProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(serviceCollection.BuildServiceProvider());
        }
        public EfCoreReverseEngineerResult GenerateFiles(ReverseEngineerOptions reverseEngineerOptions)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection()
                                    .AddScaffolding()
                                    .AddLogging();

            // Add database provider services
            switch (reverseEngineerOptions.DatabaseType)
            {
            case DatabaseType.SQLCE35:
                throw new NotImplementedException();

            case DatabaseType.SQLCE40:
                var sqlCeProvider = new SqlCeDesignTimeServices();
                sqlCeProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var serviceProvider = serviceCollection.BuildServiceProvider();
            var generator       = serviceProvider.GetService <ReverseEngineeringGenerator>();

            var tableSelectionSet = reverseEngineerOptions.Tables.Count == 0
                ? TableSelectionSet.All
                : new TableSelectionSet(reverseEngineerOptions.Tables);

            var options = new ReverseEngineeringConfiguration
            {
                ConnectionString     = reverseEngineerOptions.ConnectionString,
                ProjectPath          = reverseEngineerOptions.ProjectPath,
                OutputPath           = reverseEngineerOptions.OutputPath,
                ProjectRootNamespace = reverseEngineerOptions.ProjectRootNamespace,
                OverwriteFiles       = true,
                UseFluentApiOnly     = reverseEngineerOptions.UseFluentApiOnly,
                ContextClassName     = reverseEngineerOptions.ContextClassName,
                TableSelectionSet    = tableSelectionSet
            };

            var model = generator.GetMetadataModel(options);

            var filePaths = generator.GenerateAsync(options).GetAwaiter().GetResult();

            var errors = model.Scaffolding().EntityTypeErrors;

            var result = new EfCoreReverseEngineerResult
            {
                EntityErrors = errors,
                FilePaths    = filePaths.EntityTypeFiles,
            };

            result.FilePaths.Add(filePaths.ContextFile);

            return(result);
        }
        public static ServiceProvider Build(ReverseEngineerOptions options)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection();

            serviceCollection
            .AddEntityFrameworkDesignTimeServices()
            .AddSingleton <IOperationReporter, OperationReporter>()
            .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            if (options.UseHandleBars)
            {
                //TODO Consider being selective based on SelectedToBeGenerated
                var selected = Microsoft.EntityFrameworkCore.Design.ReverseEngineerOptions.DbContextAndEntities;
                var language = (LanguageOptions)options.SelectedHandlebarsLanguage;
                serviceCollection.AddHandlebarsScaffolding(selected, language);
                serviceCollection.AddSingleton <ITemplateFileService>(provider => new CustomTemplateFileService(options.ProjectPath));
            }

            if (options.CustomReplacers != null)
            {
                serviceCollection.AddSingleton <ICandidateNamingService>(provider => new ReplacingCandidateNamingService(options.CustomReplacers));
            }

            if (options.UseInflector)
            {
                if (options.UseLegacyPluralizer)
                {
                    serviceCollection.AddSingleton <IPluralizer, LegacyPluralizer>();
                }
                else
                {
                    serviceCollection.AddSingleton <IPluralizer, HumanizerPluralizer>();
                }
            }

            // Add database provider services
            switch (options.DatabaseType)
            {
            case DatabaseType.SQLCE35:
                throw new NotImplementedException();

            case DatabaseType.SQLCE40:
                var sqlCeProvider = new SqlCeDesignTimeServices();
                sqlCeProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLServer:
                var provider = new SqlServerDesignTimeServices();
                provider.ConfigureDesignTimeServices(serviceCollection);

                if (!string.IsNullOrEmpty(options.Dacpac))
                {
                    serviceCollection.AddSingleton <IDatabaseModelFactory, SqlServerDacpacDatabaseModelFactory>();
                }

                if (options.UseSpatial)
                {
                    var spatial = new SqlServerNetTopologySuiteDesignTimeServices();
                    spatial.ConfigureDesignTimeServices(serviceCollection);
                }

                break;

            case DatabaseType.Npgsql:
                var npgsqlProvider = new NpgsqlDesignTimeServices();
                npgsqlProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.Mysql:
                var mysqlProvider = new MySqlDesignTimeServices();
                mysqlProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            case DatabaseType.SQLite:
                var sqliteProvider = new SqliteDesignTimeServices();
                sqliteProvider.ConfigureDesignTimeServices(serviceCollection);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(serviceCollection.BuildServiceProvider());
        }