提问者:小点点

如何在桌面应用程序中使用DbContext和DI


我一直在使用Entity Framework处理几个非Web应用程序,我一直在努力寻找使用DBContext实现通用存储库的正确方法。

我搜索了很多,很多文章都是关于web应用程序的,这些应用程序的上下文很短。 在桌面方法中,我找不到合适的方法。

一种方法是dbcontext per view-model,但我不同意将UI与存储库耦合。

另一种方法是以这种方式使用using子句:

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

但是这样我们就不会有工作单元,也不能像web应用程序那样使用IOC容器

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


共1个答案

匿名用户

dbcontext是短命的:它本身代表一个工作单元。 如果您需要长期的对象状态管理,那么您可以直接使用实体框架中的ObjectStateManager

为了确保访问dbcontext,请添加一个接口idbcontextFactory(如果只有一个dbcontext类型,则只添加imydbcontextFactory),并将其注入到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();
        }
    }
}