我的简单存储库的getAll方法:
public List<ListModel> GetAllLists()
{
using (MySqlConnection connection = new MySqlConnection(this.connectionString))
{
return connection.Query<ListModel>("SELECT * FROM projectx.lists").AsList();
}
}
我正在使用我在这里找到的这个类来处理缓存:
public class CacheUtils : ICacheService
{
public TValue Get<TValue>(string cacheKey, Func<TValue> getItemCallback, double durationInMinutes = 120) where TValue : class
{
TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
if (item == null)
{
Debug.WriteLine("Not cached");
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
}
else
Debug.WriteLine("Cached!");
return item;
}
public TValue Get<TValue, TId>(string cacheKeyFormat, TId id, Func<TId, TValue> getItemCallback, double durationInMinutes = 120) where TValue : class
{
string cacheKey = string.Format(cacheKeyFormat, id);
TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
if (item == null)
{
item = getItemCallback(id);
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
}
return item;
}
}
家庭控制器:
public ActionResult Index()
{
ListRepository listRep = new ListRepository();
CacheUtils cache = new CacheUtils();
return View(cache.Get("lists", listRep.GetAllLists));
}
问题,有没有比从控制器调用帮助器更好的处理缓存的方法?理想情况下,它应该在存储库方法中。但是,我是否需要在存储库的每个方法上重复检查现有缓存数据?即:
public List<ListModel> GetAllLists()
{
var lists = Cache["lists"];
if(lists == null)
{
using (MySqlConnection connection = new MySqlConnection(this.connectionString))
{
lists = connection.Query<ListModel>("SELECT * FROM projectx.lists").AsList();
}
Cache["lists"] = lists;
}
return ((List<ListModel>)lists);
}
答案 0 :(得分:1)
使用装饰器模式,不要使用缓存逻辑来判断业务或ui。 用ninject之类的东西(或者如果你不想添加DI那样糟糕的混蛋)我建议将它标记为单个实例。
好处包括:
所以像下面这样的东西会起作用。有关如何在ninject中添加装饰器,请参阅https://stackoverflow.com/a/8910599/1073280
json_last_error
意见:也许只是为了保持代码较小,但要小心使用带有ORM的select *。如果有人重命名或删除了一个列,你将无法轻松地进行单元测试/检测故障机制。
答案 1 :(得分:0)
在我看来,它不应该在存储库中,因为它(对我来说)闻起来像违规或SRP。缓存应该是存储库之上的更高级别的服务。
您需要考虑实际需要缓存的好处。如果缓存是为了加速WEB API接口,那么将它放在控制器中是最好的方法。如果您还需要在其他地方进行缓存,请考虑引入一些中间层服务类并将缓存放在那里,但我总是以某种方式使其成为可选项。