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)
            //{
            //    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 = string.IsNullOrWhiteSpace(reverseEngineerOptions.OutputPath)
                ? reverseEngineerOptions.ProjectRootNamespace
                : $"{reverseEngineerOptions.ProjectRootNamespace}.{reverseEngineerOptions.OutputPath}";

            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);

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

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

            return(result);
        }
        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.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 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>()
            .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)
            {
                //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 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, LegacyInflectorPluralizer>();
                }
                else
                {
                    serviceCollection.AddSingleton <IPluralizer, InflectorPluralizer>();
                }
            }

            // 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);

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

                if (!string.IsNullOrEmpty(options.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();
            }

            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
            .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.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);
                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.UnsafeFullName).ToArray(),
                schemas,
                @namespace,
                "C#",
                null,
                reverseEngineerOptions.ContextClassName,
                modelOptions,
                codeOptions);

            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 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 || options.UseLegacyPluralizer)
            {
                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());
        }