倉儲
“在領域層和數據映射層之間進行中介,使用類似集合的接口來操作領域對象.” (Martin Fowler).
個人理解倉儲就是對實體進行CRUD操作的一套類,在充血模式中這套方法一般和實體放在一起,在貧血模式中一般會獨立出來放到DAL層,也就是這裏的倉儲了。
提供方法
- 提供 Insert 方法用於保存新實體.
- 提供 Update 和 Delete 方法通過實體或實體id更新或刪除實體.
- 提供 Delete 方法使用條件表達式過濾刪除多個實體.
- 實現了 IQueryable, 所以你可以使用LINQ和擴展方法 FirstOrDefault, Where, OrderBy, ToList 等…
- 所有方法都具有 sync(同步) 和 async(異步) 版本.
使用方式
private readonly IRepository<Person, Guid> _personRepository;
先看看我的使用用例,倉儲的使用是在.Application項目中,也就是在Service層
using LY.Shop.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace LY.Shop
{
public class ProductService : ShopAppService, IProductService
{
private readonly IRepository<Product> _productRepository;
public ProductService(IRepository<Product> productRepository)
{
_productRepository = productRepository;
}
//添加
public Task<ProductDto> AddAsync(ProductDto product)
{
var result = _productRepository.InsertAsync(new Product(GuidGenerator.Create()) { ProductPrice = 1, ProductUnit = "個", ProductName = product.Name }).ContinueWith(task =>
{
return product;
});
return result;
}
//讀取
public Task<ProductDto> GetAsync()
{
var result = _productRepository.FirstOrDefault();
return Task.FromResult(new ProductDto()
{
Name = result.ProductName
}); ;
}
public Task<ProductDto> GetAuthorizedAsync()
{
return Task.FromResult(
new ProductDto
{
Name = "aaa"
}
);
}
}
}
so easy,既然這樣,我們看看他都做了什麼
源碼目錄
整個代碼都是一IRepository作爲基礎接口進行實現的。
IReadOnlyBasicRepository.cs 做了一些讀取的定義,Get, Find等
IBasicRepository.cs 做了一些插入 更新 刪除等定義,
有興趣的自己去github上看吧
自定義倉儲
這個在實際業務開發過程中肯定是常用的,但是官網文檔說是不常用,我就覺得奇怪了,難道是我對默認的倉儲理解不夠深入,遺漏了一些重要功能,先給自己留個一問吧。
public class PersonRepository : EfCoreRepository<MyDbContext, Person, Guid>, IPersonRepository
{
public PersonRepository(IDbContextProvider<TestAppDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<Person> FindByNameAsync(string name)
{
return await DbContext.Set<Person>()
.Where(p => p.Name == name)
.FirstOrDefaultAsync();
}
}
官方給的例子挺好的。