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 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()
                                    .AddScaffolding(reporter)
                                    .AddSingleton <IOperationReporter, OperationReporter>()
                                    .AddSingleton <IOperationReportHandler, OperationReportHandler>();

            // 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 <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.

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

            return(result);
        }