【问题标题】:Net Core: Execute Dependency Injection with Xunit for Unit of Work Pattern and DBContextNet Core:使用 Xunit 为工作单元模式和 DBContext 执行依赖注入
【发布时间】:2020-01-03 02:45:17
【问题描述】:

我正在尝试对具有工作单元模式的基础存储库进行依赖注入,我们使用的是通用存储库(由公司架构师决定)。

出于某种原因,什么都没有保存,只是想知道在下面的依赖注入中将 DBContext 与工作单元相关联的正确方法是什么。目前在测试时收到以下空值,实体框架中没有保存任何内容。

可以使用Regular Dbcontext保存,但测试后无法使用Unit of Work模式保存值。

在 Xunit test.cs 中,似乎我需要将 TestContext 作为参数传递给 UnitofWork 构造函数,不知道如何在依赖注入中接收错误,

工作单元

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext context;
    public UnitOfWork(DbContext context)
    {
        this.context = context;
    }

    public DbSet<TEntity> DBSet<TEntity, TPrimaryKey>() where TEntity : class, IEntity<TPrimaryKey> => context.Set<TEntity>();

    public void SetAsModified<TPrimaryKey>(IEntity<TPrimaryKey> entity) => Task.Run(() => context.Entry(entity).State = EntityState.Modified);

    public async Task Save()
    {
        await context.SaveChangesAsync();
    }

    // IDisposable pattern support
    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed && disposing)
        {
            context.Dispose();
        }
        this.disposed = true;
    }

基础存储库:

public class BaseRepository<T, TPrimaryKey> : IRepository<T, TPrimaryKey> where T : class, IEntity<TPrimaryKey>
{
    private readonly IUnitOfWork unitOfWork;
    protected virtual DbSet<T> DbSet { get; }
    protected IQueryable<T> All => DbSet.AsNoTracking();

    public IUnitOfWork UnitOfWork => unitOfWork;

    public BaseRepository(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
        DbSet = unitOfWork.DBSet<T, TPrimaryKey>();
    }

    public void Insert(T entity)
    {
        DbSet.Add(entity);
    }

    public IQueryable<T> GetAll()
    {
        return All;
    }

public class BaseRepository<T> : BaseRepository<T, int>, IRepository<T> where T : class
{
    public BaseRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
    {

    }
}

XUnit 测试:

    var services = new ServiceCollection();
    services.AddDbContext<TestContext>(a => a.UseInMemoryDatabase("Test"));
    services.AddTransient<DbContext, TestContext>();
    services.AddTransient<IUnitOfWork, UnitOfWork>();
    services.AddTransient(typeof(IRepository<>), typeof(BaseRepository<>));
    ServiceProvider serviceProvider = services.BuildServiceProvider();
    var scope = serviceProvider.CreateScope();

    var testdbContext = scope.ServiceProvider.GetServices<TestContext>();
    var unitOfWork = scope.ServiceProvider.GetService<IUnitOfWork>();

    var ProductRepository = scope.ServiceProvider.GetService<IRepository<Product>>();


    ProductRepository.Insert(new Product {ProductId = 1, ProductName = "ABC";
    ProductRepository.Insert(new Product {ProductId = 2, ProductName = "DEF");
    await unitOfWork.Save();


    public Product()
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription{ get; set; }
    }

什么都没有保存。在调试期间-我在 DBSet 绿色中的值,但在执行 ProductRepository.GetAll() 时完全没有,没有意义,试图弄清楚

更新

仅使用 DbContext 保存时,它可以工作。 但是,无法使用 Unit of Work 保存。

TestContext.Product.Add(expectedResult[0]);
TestContext.Product.Add(expectedResult[1]);
TestContext.SaveChanges();

参考问题: Net Core: Execute All Dependency Injection in Xunit Test for AppService, Repository, etc

【问题讨论】:

    标签: c# .net asp.net-core .net-core xunit


    【解决方案1】:

    您将您的服务注册为临时服务,这意味着每次需要解析或注入服务时,DI 容器都会创建新实例,因此注入到 IRepository&lt;&gt; 中的 IUnitOfWork 实例与您不同'正在使用GetService&lt;IUnitOfWork&gt;()。您可以通过使用services.AddScoped 注册服务来解决它,这样每个服务的单个实例将在每个打开的范围内创建。

    【讨论】:

      猜你喜欢
      • 2021-10-23
      • 2021-11-10
      • 2016-06-26
      • 2020-06-30
      • 2019-12-11
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多