C# 在编写WPF应用程序时,我应该将DbContext注册到Unity容器中的哪个生命周期管理器?

C# 在编写WPF应用程序时,我应该将DbContext注册到Unity容器中的哪个生命周期管理器?,c#,wpf,repository,entity-framework-core,prism,C#,Wpf,Repository,Entity Framework Core,Prism,我正在使用著名的MVVM设计模式在框架顶部编写一个新的C#应用程序。我正在使用Unity IoC容器来帮助我管理依赖项 我正在使用它与数据库进行交互。但是,我不想将我的应用程序与实体框架核心紧密耦合,因此我实现了存储库和UnitOfWork模式,以便在需要时轻松替换实体框架核心实现 我的存储库实现提供了一个名为Save()的方法,该方法调用EF Core的SaveChanges()方法。存储库被注入到我的业务服务中,以便我的业务服务公开一个方法来执行单个任务。例如,如果我想创建一个新订单,我将调

我正在使用著名的MVVM设计模式在框架顶部编写一个新的C#应用程序。我正在使用Unity IoC容器来帮助我管理依赖项

我正在使用它与数据库进行交互。但是,我不想将我的应用程序与实体框架核心紧密耦合,因此我实现了
存储库
UnitOfWork
模式,以便在需要时轻松替换实体框架核心实现

我的存储库实现提供了一个名为
Save()
的方法,该方法调用EF Core的
SaveChanges()
方法。存储库被注入到我的业务服务中,以便我的业务服务公开一个方法来执行单个任务。例如,如果我想创建一个新订单,我将调用
create(orderViewModel)
方法,该方法在内部调用
OrderRepository
上的
Add()
Save()
方法

此外,
UnitOfWork
提供了
Save()
BeginTransaction()
Commit()
Rollback()
方法,允许我控制事务行为。换句话说,它将给我在需要时提交或回滚SQL事务的灵活性

为了更好地解释我的用例,下面是一个示例,演示了如何在不使用事务或工作单元的情况下直接使用业务服务向数据库添加新订单

OrdersService.Create(orderViewModel); // this will call the `Add` and the `Save()` methods on the OrderRepository;
下面是另一个示例,演示如何使用业务服务将新订单和订单项添加到数据库中,同时使用工作单元启动事务并控制事务

using(var transaction = UnitOfWork.BeginTransaction())
{
    try 
    {
        var order = OrdersService.Create(orderViewModel);
        OrdersService.CreateRange(order.Id, orderItemsViewModel);
        transaction.Commit();
    } 
    catch(Exception e)
    {
        Log.Add(e);
        transaction.RollBack();
    }
}
在上面的第二个示例中,即使
OrdersService.Save
OrdersService.savegrange
都调用
SaveChanges()
方法,数据也不会提交到数据库,因为我正在用事务包装它们

using(var transaction = UnitOfWork.BeginTransaction())
{
    try 
    {
        var order = OrdersService.Create(orderViewModel);
        OrdersService.CreateRange(order.Id, orderItemsViewModel);
        transaction.Commit();
    } 
    catch(Exception e)
    {
        Log.Add(e);
        transaction.RollBack();
    }
}
问题:我应该用什么注册
DbContext
IUnitOfWork
和我的每个存储库

在web环境中,我将使用注册所有内容,然后在请求过程中重用相同的
DbContext
,所有内容都正常工作,
DbContext
将在http请求结束时处理。但不知道如何在WPF应用程序中注册所有内容,在WPF应用程序中,我仍然可以使用事务控制所有内容,同时允许存储库调用
SaveChanges()

如果需要,这里是我的
EntityRepository
实现

public class EntityRepository<TEntity, TKeyType> : IRepository<TEntity, TKeyType>
    where TEntity : class
    where TKeyType : struct
{
    protected readonly DbContext Context;
    protected readonly DbSet<TEntity> DbSet;

    public EntityRepository(DbContext context)
    {
        Context = context;
        DbSet = context.Set<TEntity>();
    }

    public TEntity Get(TKeyType id)
    {
        return DbSet.Find(id);
    }

    public IEnumerable<TEntity> GetAll()
    {
        return DbSet.ToList();
    }

    public bool Any(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.Any(predicate);
    }

    public IQueryable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.Where(predicate);
    }

    public TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
    {
        return DbSet.SingleOrDefault(predicate);
    }

    public virtual TEntity Add(TEntity entity)
    {
        var record = Context.Add(entity);
        record.State = EntityState.Added;

        return entity;
    }

    public virtual IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
    {
        Context.AddRange(entities);

        return entities;
    }

    public void Remove(TEntity entity)
    {
        Context.Remove(entity).State = EntityState.Deleted;
    }

    public void RemoveRange(IEnumerable<TEntity> entities)
    {
        Context.RemoveRange(entities);
    }

    public void Update(TEntity entity)
    {
        DbSet.Attach(entity);
        var record = Context.Entry(entity);
        record.State = EntityState.Modified;
    }

    public IQueryable<TEntity> Query()
    {
        return DbSet;
    }

    public void Save()
    {
        Context.SaveChanges();
    }
}
如果您的DI不支持作用域,那么瞬态(每个视图一个实例)生命周期将是一种选择,但是您需要将正在传递到repo和unitOfWork中的DbContext抽象出来,否则将在其中传递DbContext的新实例。在构建页面时,将创建一个新实例,在离开该视图时,应丢弃该DBContext。UnitOfWork将遵循与您不希望UnitOfWork跨越DBContext的多个实例相同的路径。 看见否则,如果您的DI具有容器层次结构的概念,并且您能够为每个视图创建一个容器范围,那么单例将在这个实例中工作,您不需要上面提到的任何抽象,并且将更容易使用