C# EntityFrameworkCore.Design(DesignTimeServicesBuilder.cs)中的服务替换

C# EntityFrameworkCore.Design(DesignTimeServicesBuilder.cs)中的服务替换,c#,entity-framework,dependency-injection,entity-framework-core,scaffolding,C#,Entity Framework,Dependency Injection,Entity Framework Core,Scaffolding,我试图用自己的自定义实现替换Microsoft.EntityFrameworkCore.Design中的StringBuilderCodeWriter,以便修改脚手架以生成存储库模式类 我正在覆盖DesignTimeServicesBuilder中的ConfigureServices方法以添加我的CustomStringBuilderCodeWriter,但我无法让它使用我的实现 我正在使用EF Core 1.1在.NET Core控制台应用程序中对此进行测试 Program.cs using

我试图用自己的自定义实现替换Microsoft.EntityFrameworkCore.Design中的
StringBuilderCodeWriter
,以便修改脚手架以生成存储库模式类

我正在覆盖
DesignTimeServicesBuilder
中的
ConfigureServices
方法以添加我的
CustomStringBuilderCodeWriter
,但我无法让它使用我的实现

我正在使用EF Core 1.1在.NET Core控制台应用程序中对此进行测试

Program.cs

using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;

namespace RepositoryPattern
{
    public class Program
    { 
        public static void Main(string[] args)
        {
            IOperationReportHandler handler = new OperationReportHandler();
            IOperationReporter reporter = new OperationReporter(handler);

            var startup = new StartupInvoker(reporter, Assembly.Load(new AssemblyName("Microsoft.EntityFrameworkCore.Design")), "ADONET_DATA_DIR", @"ANOTHER_OUTPUT_PATH");
            CustomDesignTimeServicesBuilder servicesBuilder = new CustomDesignTimeServicesBuilder(startup);

            var services = servicesBuilder.Build("Microsoft.EntityFrameworkCore.SqlServer");

            var generator = services.GetRequiredService<ReverseEngineeringGenerator>();

            // The TableSelectionSet seems to be ignored for some reason, ignore for now.
            var tableSelectionSet = new TableSelectionSet(new List<string> { "Customers", "Employees" }, new List<string> { "dbo" });
            var configuration = new ReverseEngineeringConfiguration
            {
                ConnectionString = @"Server=(localdb)\Samples;Database=Northwind;Trusted_Connection=True;",
                ContextClassName = "NorthwindContext",
                ProjectPath = @"PROJECT_PATH_GOES_HERE",
                ProjectRootNamespace = "RepositoryPattern",
                OutputPath = @"WHERE_THE_GENERATED_FILES_GO",
                TableSelectionSet = tableSelectionSet,
                UseFluentApiOnly = true,
                OverwriteFiles = true
            };

            generator.GenerateAsync(configuration, new CancellationToken());
        }    
    }
}
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.Extensions.DependencyInjection;

namespace RepositoryPattern 
{
    public class CustomDesignTimeServicesBuilder : DesignTimeServicesBuilder
    {
        public CustomDesignTimeServicesBuilder(StartupInvoker startupInvoker) : base(startupInvoker)
        { }

        protected override IServiceCollection ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<CSharpHelper>();
            services.AddSingleton<CSharpMigrationOperationGenerator>();
            services.AddSingleton<CSharpSnapshotGenerator>();
            services.AddSingleton<MigrationsCodeGenerator, CSharpMigrationsGenerator>();
            services.AddScaffolding();
            services.AddSingleton<StringBuilderCodeWriter, CustomStringBuilderCodeWriter>();
            services.AddLogging();

            return base.ConfigureServices(services);
        }
    }
}
使用System.Collections.Generic;
运用系统反思;
使用Microsoft.EntityFrameworkCore.Design;
使用Microsoft.EntityFrameworkCore.Design.Internal;
使用Microsoft.EntityFrameworkCore.Scaffolding;
使用Microsoft.EntityFrameworkCore.Scaffolding.Internal;
使用Microsoft.Extensions.DependencyInjection;
使用系统线程;
名称空间存储模式
{
公共课程
{ 
公共静态void Main(字符串[]args)
{
IOperationReportHandler=新操作ReportHandler();
IOperationReporter=新操作报告程序(处理程序);
var startup=new StartupInvoker(reporter,Assembly.Load(new AssemblyName(“Microsoft.EntityFrameworkCore.Design”),“ADONET_DATA_DIR”,@“另一个输出路径”);
CustomDesignTimeServicesBuilder servicesBuilder=新CustomDesignTimesServicesBuilder(启动);
var services=servicesBuilder.Build(“Microsoft.EntityFrameworkCore.SqlServer”);
var generator=services.GetRequiredService();
//由于某种原因,表选择集似乎被忽略,请暂时忽略。
var tableSelectionSet=newtableselectionset(新列表{“客户”、“员工”},新列表{“dbo”});
var配置=新反向工程配置
{
ConnectionString=@“服务器=(localdb)\Samples;数据库=北风;可信连接=真;”,
ContextClassName=“NorthwindContext”,
ProjectPath=@“项目路径在这里”,
ProjectRootNamespace=“RepositoryPattern”,
OutputPath=@“生成文件的位置”,
TableSelectionSet=TableSelectionSet,
UseFluentApiOnly=true,
OverwriteFiles=true
};
generator.GenerateSync(配置,新的CancellationToken());
}    
}
}
CustomDesignTimeServicesBuilder.cs

using System.Collections.Generic;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.EntityFrameworkCore.Scaffolding;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;

namespace RepositoryPattern
{
    public class Program
    { 
        public static void Main(string[] args)
        {
            IOperationReportHandler handler = new OperationReportHandler();
            IOperationReporter reporter = new OperationReporter(handler);

            var startup = new StartupInvoker(reporter, Assembly.Load(new AssemblyName("Microsoft.EntityFrameworkCore.Design")), "ADONET_DATA_DIR", @"ANOTHER_OUTPUT_PATH");
            CustomDesignTimeServicesBuilder servicesBuilder = new CustomDesignTimeServicesBuilder(startup);

            var services = servicesBuilder.Build("Microsoft.EntityFrameworkCore.SqlServer");

            var generator = services.GetRequiredService<ReverseEngineeringGenerator>();

            // The TableSelectionSet seems to be ignored for some reason, ignore for now.
            var tableSelectionSet = new TableSelectionSet(new List<string> { "Customers", "Employees" }, new List<string> { "dbo" });
            var configuration = new ReverseEngineeringConfiguration
            {
                ConnectionString = @"Server=(localdb)\Samples;Database=Northwind;Trusted_Connection=True;",
                ContextClassName = "NorthwindContext",
                ProjectPath = @"PROJECT_PATH_GOES_HERE",
                ProjectRootNamespace = "RepositoryPattern",
                OutputPath = @"WHERE_THE_GENERATED_FILES_GO",
                TableSelectionSet = tableSelectionSet,
                UseFluentApiOnly = true,
                OverwriteFiles = true
            };

            generator.GenerateAsync(configuration, new CancellationToken());
        }    
    }
}
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.Extensions.DependencyInjection;

namespace RepositoryPattern 
{
    public class CustomDesignTimeServicesBuilder : DesignTimeServicesBuilder
    {
        public CustomDesignTimeServicesBuilder(StartupInvoker startupInvoker) : base(startupInvoker)
        { }

        protected override IServiceCollection ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<CSharpHelper>();
            services.AddSingleton<CSharpMigrationOperationGenerator>();
            services.AddSingleton<CSharpSnapshotGenerator>();
            services.AddSingleton<MigrationsCodeGenerator, CSharpMigrationsGenerator>();
            services.AddScaffolding();
            services.AddSingleton<StringBuilderCodeWriter, CustomStringBuilderCodeWriter>();
            services.AddLogging();

            return base.ConfigureServices(services);
        }
    }
}
使用Microsoft.EntityFrameworkCore.Migrations.Design;
使用Microsoft.EntityFrameworkCore.Scaffolding.Internal;
使用Microsoft.EntityFrameworkCore.Design.Internal;
使用Microsoft.Extensions.DependencyInjection;
名称空间存储模式
{
公共类CustomDesignTimeServicesBuilder:DesignTimeServicesBuilder
{
公共CustomDesignTimeServicesBuilder(StartupInvoker StartupInvoker):基础(StartupInvoker)
{ }
受保护的覆盖IServiceCollection配置服务(IServiceCollection服务)
{
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
服务。AddScaffolding();
services.AddSingleton();
services.AddLogging();
返回base.ConfigureServices(服务);
}
}
}
CustomStringBuilderCodeWriter.cs 此实现在额外类中创建,同时通过EntityConfiguration循环以生成存储库样式的类

using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Scaffolding.Configuration.Internal;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

namespace RepositoryPattern
{
    /// <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 class CustomStringBuilderCodeWriter : StringBuilderCodeWriter
    {
        public CustomStringBuilderCodeWriter(
            IFileService fileService, 
            DbContextWriter dbContextWriter, 
            EntityTypeWriter entityTypeWriter) 
            : base(fileService, dbContextWriter, entityTypeWriter)
        { }

        /// <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 override Task<ReverseEngineerFiles> WriteCodeAsync(
            ModelConfiguration modelConfiguration,
            string outputPath,
            string dbContextClassName,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            var resultingFiles = new ReverseEngineerFiles();

            var generatedCode = DbContextWriter.WriteCode(modelConfiguration);

            // output DbContext .cs file
            var dbContextFileName = dbContextClassName + FileExtension;
            var dbContextFileFullPath = FileService.OutputFile(
                outputPath, dbContextFileName, generatedCode);
            resultingFiles.ContextFile = dbContextFileFullPath;

            foreach (var entityConfig in modelConfiguration.EntityConfigurations)
            {
                generatedCode = EntityTypeWriter.WriteCode(entityConfig);

                // output EntityType poco .cs file
                var entityTypeFileName = entityConfig.EntityType.DisplayName() + FileExtension;
                var entityTypeFileFullPath = FileService.OutputFile(
                    outputPath, entityTypeFileName, generatedCode);
                resultingFiles.EntityTypeFiles.Add(entityTypeFileFullPath);

                RepositoryWriter repositoryWriter = new RepositoryWriter(new CSharpUtilities());
                generatedCode = repositoryWriter.WriteCode(entityConfig);

                // output Repository .cs file
                var repositoryFileName = entityConfig.EntityType.DisplayName() + "Repository" + FileExtension;
                var repositoryFileFullPath = FileService.OutputFile(
                    outputPath, repositoryFileName, generatedCode);
            }

            return Task.FromResult(resultingFiles);
        }
    }
}
使用系统线程;
使用System.Threading.Tasks;
使用JetBrains.Annotations;
使用Microsoft.EntityFrameworkCore.Metadata.Internal;
使用Microsoft.EntityFrameworkCore.Scaffolding.Configuration.Internal;
使用Microsoft.EntityFrameworkCore.Scaffolding.Internal;
使用Microsoft.EntityFrameworkCore.Utilities;
名称空间存储模式
{
/// 
///此API支持实体框架核心基础架构,不打算使用
///直接从您的代码。此API可能会在将来的版本中更改或删除。
/// 
公共类CustomStringBuilderCodeWriter:StringBuilderCodeWriter
{
公共CustomStringBuilderCodeWriter(
IFileService文件服务,
DbContextWriter DbContextWriter,
实体打字机(实体打字机)
:base(文件服务、dbContextWriter、entityTypeWriter)
{ }
/// 
///此API支持实体框架核心基础架构,不打算使用
///直接从您的代码。此API可能会在将来的版本中更改或删除。
/// 
公共覆盖任务writecodesync(
模型配置模型配置,
字符串输出路径,
字符串dbContextClassName,
CancellationToken CancellationToken=默认值(CancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
var resultingFiles=新的反向工程文件();
var generatedCode=DbContextWriter.WriteCode(modelConfiguration);
//输出DbContext.cs文件
var dbContextFileName=dbContextClassName+FileExtension;
var dbContextFileFullPath=FileService.OutputFile(
outputPath、dbContextFileName、generatedCode);
resultingFiles.ContextFile=dbContextFileFullPath;
foreach(modelConfiguration.EntityConfiguration中的变量EntityConfiguration)
{
generatedCode=EntityTypeWriter.WriteCode(entityConfig);
//输出EntityType poco.cs文件
var entityTypeFileName=entityConfig.EntityType.DisplayName()+文件扩展名;
var entityTypeFileFullPath=FileService.OutputFile(
输出路径,