[英]Unit testing for IDomainService with ASP.NET Boilerplate
我正在对ABP进行单元测试,但以下错误提示:
无法访问已处置的对象。 导致此错误的常见原因是,处理从依赖项注入中解决的上下文,然后稍后尝试在应用程序中的其他位置使用相同的上下文实例。 如果在上下文上调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。 如果使用依赖项注入,则应让依赖项注入容器负责处理上下文实例。 对象名称:“ XXXDbContext”。
这是我的详细步骤:
应用服务
public async Task<ProductDto> CreateProduct(CreateProductInput input) { var existing = // await _productManager.ProductRepository.FirstOrDefaultAsync(p => p.Name == input.Name); await _productManager.Products.Where(p => p.Name == input.Name).FirstOrDefaultAsync(); if (existing != null) throw new UserFriendlyException(L("ExistedRepeatedAd")); var newAdEntity = ObjectMapper.Map<Product>(input); // Rest of the code }
产品经理
public class ProductManager : IDomainService { private readonly IRepository<Product, long> _ProductRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; public ProductsManager( IRepository<Product, long> ProductRepository, IUnitOfWorkManager unitOfWorkManager) { _ProductRepository = ProductRepository; _unitOfWorkManager = unitOfWorkManager; } #region Products public IRepository<Product, long> ProductRepository { get { return _ProductRepository; } } public IQueryable<Product> Products { get { return _ProductRepository.GetAll(); } } public async Task<Product> CreateProduct(Product input) { var result = await _ProductRepository.InsertAsync(input); await _unitOfWorkManager.Current.SaveChangesAsync(); return result; } #endregion }
它将在此行引发错误:
await _adManager.Ads.Where(p => p.Name == input.Name).FirstOrDefaultAsync();
但是,如果我改用它,它将起作用:
await _adManager.AdRepository.FirstOrDefaultAsync(p => p.Name == input.Name);
另外,我在上面的代码_unitOfWorkManager.Current
作为null
。
有什么建议吗?
添加[UnitOfWork]
属性并使其成为virtual
方法:
[UnitOfWork]
public virtual async Task<ProductDto> CreateProduct(CreateProductInput input)
{
var existing = await _productManager.Products
.Where(p => p.Name == input.Name)
.FirstOrDefaultAsync();
// ...
}
[UnitOfWork]
public virtual async Task<Product> CreateProduct(Product input)
{
var result = await _ProductRepository.InsertAsync(input);
await _unitOfWorkManager.Current.SaveChangesAsync();
return result;
}
请参阅: UnitOfWork属性限制
您可以将UnitOfWork属性用于:
- 在接口上使用的类的所有公共或公共虚拟方法(例如在服务接口上使用的应用程序服务)。
- 用于自注入类的所有公共虚拟方法(如MVC控制器和Web API控制器 )。
- 所有受保护的虚拟方法。
您可以注入IUnitOfWorkManager
来显式启动UnitOfWork
:
public async Task<Product> CreateProduct(Product input)
{
using (var uow = _unitOfWorkManager.Begin())
{
var result = await _ProductRepository.InsertAsync(input);
await _unitOfWorkManager.Current.SaveChangesAsync();
await uow.CompleteAsync();
return result;
}
}
通过为我的appservice创建接口,然后在测试项目中解决此接口,可以解决我的问题。
感谢aaron的建议,但是在我的每个应用程序服务中使用uniofwork会很复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.