我在很多地方重复这个代码:
public class ProductTypeService : IProductTypeService
{
public async Task<IList<ProductType>> GetAllAsync(int sectionId = -1)
{
string key = "ProductTypeService_" + "GetAllAsync" + sectionId;
var list = _memoryCacheService.Get<IList<ProductType>>(key);
if (list == null)
{
list = await _repository.GetAllAsync(sectionId);
_memoryCacheService.Save(key, list);
}
return list;
}
public class VendorService : IVendorService
{
public async Task<IList<Vendor>> GetAllAsync()
{
string key = "VendorService_" + "GetAllAsync";
var list = _memoryCacheService.Get<IList<Vendor>>(key);
if (list == null)
{
list = await _repository.GetAllAsync();
_memoryCacheService.Save(key, list);
}
return list;
}关键是类+方法+参数的组合。唯一的改变是_repository.XX(XX, XX, ...........)。我怎么才能把它弄干?
发布于 2014-10-23 09:39:18
包含通用方法和实现的通用服务实现。
我们将需要一个类,它可以成为到存储库和缓存的桥梁,因此可以定义它为BaseService。这意味着我们将以一种通用的方式在不同的repository+cache组合中使用它。这里没有黑魔法,继续前进。
首先,我们需要从问题中的两个服务实现中提取常见的内容:
public abstract class BaseService<T>
{
private ObjectCache ObjectCache { get; set; }
private IRepository<T> Repository { get; set; }
protected BaseService(IRepository<T> repository)
: this(MemoryCache.Default, repository)
{
}
protected BaseService(ObjectCache objectCache, IRepository<T> repository)
{
ObjectCache = objectCache;
Repository = repository;
}
protected virtual string GetCacheKey(string suffix, int sectionId = -1)
{
return GetType().Name + "_" + suffix + sectionId;
}
protected virtual async Task<ICollection<T>> GetAllAsyncValueFactory()
{
return await Repository.GetAllAsync();
}
public virtual async Task<ICollection<T>> GetAllAsync(int sectionId = -1)
{
var key = GetCacheKey("GetAllAsync", sectionId);
var list = ObjectCache.Get(key) as ICollection<T>;
if (list == null)
{
return ObjectCache.AddOrGetExisting(key, await GetAllAsyncValueFactory(), new CacheItemPolicy
{
//TODO: define cache policy
}) as ICollection<T>;
}
return list;
}
}这里我们要做的是在构造函数中定义我们需要的东西:存储库和ObjectCache,但是如果没有其他任何东西,我们可以使用默认的MemoryCache实例。
主要是我提取了代码中通常使用的所有逻辑,但是使用了通用实现(提示:不要使用IList是一个脏接口)。每个方法都是虚拟的,因此可以在派生类中轻松地重写它们,您可以定义不同的缓存键,或者可以告诉您如何从当前存储库获取数据。
因为泛型基类,所以我们只需要在接口实现类中定义构造函数,因为您可以这样做:
public class ProductTypeService : BaseService<ProductType>, IProductTypeService
{
public ProductTypeService(ObjectCache objectCache, IRepository<ProductType> repository)
: base(objectCache, repository)
{
}
public ProductTypeService(IRepository<ProductType> repository)
: base(repository)
{
}
}构造函数实现将根据您未知的需求而有所不同。
https://codereview.stackexchange.com/questions/67655
复制相似问题