如何在桌面应用程序中将DbContext与DI一起使用

问题描述 投票:0回答:1

[我一直在使用Entity Framework处理多个非Web应用程序,但一直很难为我找到一种使用DbContext实现Generic Repository的正确方法。

我已经搜索了很多,很多文章都是关于具有短暂生存期的Web应用程序的。在桌面方法中,我找不到合适的方法。

一种方法是DbContext per ViewModel,但我不同意将View与Repository层耦合。

[另一个正在以这种方式使用using子句:

using(var context = new AppDbContext())
{
    // ...
}

但是这样,我们将没有Unit of Work,也不能使用IoC Containers

那么在桌面应用程序中使用DbContext的解决方案是什么?

c# wpf winforms entity-framework dependency-injection
1个回答
1
投票

A DbContext被认为是短暂的:它本身代表一个工作单元。如果需要长期的对象状态管理,则可以直接在Entity Framework中使用ObjectStateManager

为了确保对DbContext的访问,请添加接口IDbContextFactory<TDbContext>(如果只有一个IMyDbContextFactory类型,则只需添加DbContext),然后将其注入到ViewModels中,并使用一个短暂的DbContext它:

interface IDbContextFactory<TDbContext>
    where TDbContext : DbContext
{
    TDbContext Create();
}

// Configure:

void ConfigureServices( YourContainer container )
{
    container.RegisterSingleton( IDbContextFactory<YourDbContextType1>, // etc );
    container.RegisterSingleton( IDbContextFactory<YourDbContextType2>, // etc );
    container.RegisterSingleton( IDbContextFactory<YourDbContextType3>, // etc );
}

// Usage:

public class LongLivedViewModel
{
    private readonly IDbContextFactory<YourDbContextType3> dbFactory;

    public LongLivedViewModel( IDbContextFactory<YourDbContextType3> dbFactory)
    {
        this.dbFactory = dbFactory ?? throw new ArgumentNullException(nameof(dbFactory));

        this.DoSomethingCommand = new RelayCommand( this.DoSomethingAsync )
    }

    public RelayCommand DoSomethingCommand { get; }

    public async RelayCommand DoSomethingAsync()
    {
        using( YourDbContextType3 db = this.dbFactory.Create() )
        {
            // do stuff

            await db.SaveChangesAsync();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.