具有通用模式的WPF EF核心依赖注入

时间:2020-07-22 10:09:16

标签: c# wpf dependency-injection entity-framework-core

目前,我正在尝试WPF / EFCore和DI。我已经设置了Application类来注册不同的/即将推出的服务,如下所示:

public partial class App : Application
{
    private IHost AppHost;

    public App()
    {
        AppHost = Host.CreateDefaultBuilder()
                .ConfigureServices((context, services) => 
                {
                    ConfigureServices(context.Configuration, services);
                })
                .Build();
    }

    private void ConfigureServices(IConfiguration Configuration, IServiceCollection Services)
    {
        Services.AddDbContext<AppDataContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("ProdToolDb"));
        });

        Services.AddSingleton<MainWindow>();
    }


    protected override async void OnStartup(StartupEventArgs e)
    {
        await AppHost.StartAsync();

        MainWindow MainWindow = AppHost.Services.GetRequiredService<MainWindow>();
        MainWindow.Show();

        base.OnStartup(e);
    }


    protected override async void OnExit(ExitEventArgs e)
    {
        using (AppHost)
        {
            await AppHost.StopAsync();
        }
        base.OnExit(e);
    }

}

当然,我有appr。也有DataContext个课程:

public class AppDataContext : DbContext
{
    public AppDataContext(DbContextOptions<AppDataContext> options) : base(options) { }

    public DbSet<Capacity> Capacities { get; set; }
    public DbSet<CapacityType> CapacityTypes { get; set; }
}

public class AppDataContextFactory : IDesignTimeDbContextFactory<AppDataContext>
{
    public AppDataContext CreateDbContext(string[] args = null)
    {
        DbContextOptionsBuilder<AppDataContext> OptionsBuilder = new DbContextOptionsBuilder<AppDataContext>();
        IConfigurationRoot Config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

        OptionsBuilder.UseSqlServer(Config.GetConnectionString("ProdToolDb"));

        return new AppDataContext(OptionsBuilder.Options);
    }
}

在另一个问题中,我被告知,为了使迁移与EF Core配合使用,我必须使用IDesignTimeDbContextFactory

现在,进一步,我设置了通用模式实现。我创建了一个界面:

public interface IDataService<T>
{
    Task<IEnumerable<T>> GetAll();

    Task<T> Get(int Id);

    Task<T> Create(T Entity);

    Task<T> Update(int Id, T Entity);

    Task<bool> Delete(int Id);
}

及其实现:

public class GenericDataService<T> : IDataService<T> where T : class
{
    private readonly AppDataContextFactory ContextFactory;

    public GenericDataService(AppDataContextFactory contextFactory)
    {
        ContextFactory = contextFactory;
    }

    public async Task<T> Create(T Entity)
    {
        using (AppDataContext Context = ContextFactory.CreateDbContext())
        {
            await Context.Set<T>().AddAsync(Entity);
            await Context.SaveChangesAsync();

            return Entity;
        }
    }

    ... other methods omitted for brevity
}

我有以下问题:

  1. 由于我使用IDesignTimeDbContextFactory来创建和配置DataContext,因此启动中的此调用是否多余?

         Services.AddDbContext<AppDataContext>(options =>
         {
             options.UseSqlServer(Configuration.GetConnectionString("ProdToolDb"));
         });
    

还是应该代替它创建IDesignTimeDbContextFactory服务并注册它?如果是,那怎么办?

  1. 正如您在IDataService实现中所看到的,我直接使用AppDataContextFactoryAppDataContext,而不是使用DI技术。我应该如何修改代码才能使用DI?

  2. 如果我想用DI处理以上所有内容,我必须在启动类中注册/添加GenericDataService<T>,对吗?我该怎么办?

请告知。

谢谢。

编辑:

我也阅读了链接的博客条目和其他条目,现在我明白了,为什么要说通用模式是反模式。我将把它扔掉,并专注于常规WPF绑定方法和视图/视图模型的DI。

0 个答案:

没有答案