我有大约30个数据访问类,它们都包含一个带有一些参数的GetAll方法。
我在它们中的代码看起来像下面这样:
public IEnumerable<IHierarchyDivisionDailyResult> GetAll(short masterId, DateTime startDate, short gbuId)
{
var cacheKey = this.Cache.CreateCacheKey(this, masterId, startDate, gbuId);
var result = this.Cache.GetList<IHierarchyDivisionDailyResult>(cacheKey);
if (result != null) return result;
lock (LockObject)
{
result = this.Cache.GetList<IHierarchyDivisionDailyResult>(cacheKey);
if (result != null) return result;
using (var dataContext = OscaDataContext.CreateWithCustomTimeOut())
{
result = dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList();
this.Cache.Add(cacheKey, result);
}
}
return result;
}
我想重构代码,以便删除重复的代码。这怎么可能呢?
每个实现的共同/不同之处是:
- CreateCacheKey总是获取所有输入参数
- 缓存。GetList -虽然类型可以不同
- GetAll方法的返回类型在每个实现中都是不同的
- 锁存在于所有这些
- dataContext对象总是如上所述创建的
- dataContext.Entity(…)也是不同的
我认为一个可能的选择是使用Reflection来找出输入参数和输出类型,然后我将能够合并大部分代码,但是我读过的Reflection方法的性能不会很好。
最理想的是能够在方法中添加一个"Cache"属性,这样结果就会自动缓存!
[Cache]
public IEnumerable GetAll(short masterId, DateTime startDate, short gbuId)
{
using (var dataContext = OscaDataContext.CreateWithCustomTimeOut())
{
return dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList();
}
}
你觉得怎么样?
谢谢,
如果我是你,我会创建一个抽象基类,它具有像这样的通用GetAll方法。
public abstract class DataAccessBase<T> where T : VehicleBase
{
public virtual T GetAll(short masterId, DateTime startDate, short gbuId)
{
...
}
}
然后你可以创建这个的具体实现…
public class CarDataAccess : DataAccessBase<Car>
{
public override Car GetAll(short masterId, DateTime startDate, short gbuId)
{
...
}
}
public class VanDataAccess : DataAccessBase<Van>
{
public override Van GetAll(short masterId, DateTime startDate, short gbuId)
{
...
}
}
在基类中,你可以放置所有东西的通用行为,然后在重写方法中,你可以放置任何特定于你正在处理的特定类型的东西。
不使用Cars和Vans,这里有一个更具体到你的代码的例子…
public abstract class DataAccessBase<T>
{
public virtual IEnumerable<T> GetAll(short masterId, DateTime startDate, short gbuId)
{
var cacheKey = this.Cache.CreateCacheKey(this, masterId, startDate, gbuId);
List<T> result = this.Cache.GetList<T>(cacheKey);
if (result != null) return result;
lock (LockObject)
{
result = this.Cache.GetList<T>(cacheKey);
if (result != null) return result;
using (var dataContext = OscaDataContext.CreateWithCustomTimeOut())
{
result = this.GetResult(dataContext, masterId, startDate, gbuId);
this.Cache.Add(cacheKey, result);
}
}
return result;
}
protected abstract List<T> GetResult(var dataContext, short masterId, DateTime startDate, short gbuId);
}
public class HierarchyDivisionDailyResultDataAccess : DataAccessBase<IHierarchyDivisionDailyResult>
{
public virtual IEnumerable<IHierarchyDivisionDailyResult> GetAll(short masterId, DateTime startDate, short gbuId)
{
return base.GetAll(masterId, startDate, gbuId);
}
protected override List<IHierarchyDivisionDailyResult> GetResult(var dataContext, short masterId, DateTime startDate, short gbuId)
{
return dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList();
}
}