【发布时间】:2020-08-27 12:59:00
【问题描述】:
我有MemoryCache 对象(应用程序、配置等),我将它们注册为Singleton。还有一些作用域存储库,可以从 db 中选择数据来填充缓存。
例如这里是Singleton注册的类,
public class ApplicationCache : MultipleLoadCache<Application>
{
public ApplicationCache()
{
}
}
MultipleLoadCache 覆盖CacheItemPolicy,(还有SingleLoadCache),
public class MultipleLoadCache<TEntity> : SmartCache<TEntity> where TEntity : class
{
public MultipleLoadCache()
{
}
protected override CacheItemPolicy SetPolicy()
{
return new CacheItemPolicy()
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(15)
};
}
}
基类是,
public class SmartCache<TEntity> : IDisposable where TEntity : class
{
public bool TryGetList(IRepository<TEntity> repository, out List<TEntity> valueList)
{
valueList = null;
lock (cacheLock)
{
GenerateCacheIfNotExists(repository, out valueList);
if (valueList == null || valueList.Count == 0)
{
valueList = (List<TEntity>)_memoryCache.Get(key);
}
}
return valueList != null;
}
我知道作用域服务不能注入单例类。所以我更喜欢使用方法注入。
private void GenerateCacheIfNotExists(IRepository<TEntity> repository, out List<TEntity> list)
{
list = null;
if (!_memoryCache.Any(x => x.Key == key)) // if key not exists, get db records from repo.
{
IEnumerable<TEntity> tempList = repository.GetList();
list = tempList.ToList();
_cacheItemPolicy = SetPolicy();
SetCacheList(list);
}
}
}
在控制器上,我尝试获取缓存值,但这部分对我来说似乎是错误的。如果我尝试获取缓存值,我不应该将存储库作为参数传递。
private readonly ApplicationCache _appCache;
public LogController(ApplicationCache appCache)
{
_appCache = appCache;
}
[HttpPost]
[Route("Register")]
public List<Application> Register([FromServices] IApplicationRepository repository)
{
List<Application> cf;
_appCache.TryGetList(repository, out cf);
return cf;
}
另外,通过方法注入。我也无法使用CacheItemPolicy 的RemovedCallBack 事件。因为,当回调触发(重新加载缓存)时,我需要存储库再次从数据库中获取记录。
这个设计看起来不错,使用MemoryCache的回调事件来做到这一点的最佳设计是什么?
更新 1-
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddMemoryCache();
services.AddSingleton(x => new ApplicationCache());
services.AddScoped<IApplicationRepository, ApplicationRepository>();
}
谢谢,
【问题讨论】:
-
你应该有一个 DataRepository 类,它有两个依赖项 1 - 缓存层和 2- 数据访问层.. 这样你就可以按照你想要的方式注入这两个依赖项......
-
你能展示你的
StartupConfigureServices例程,你在哪里注入所有东西吗? -
@ChetanRanpariya 这个问题与“存储库”anti模式无关。它专门用于使用范围服务,.NET Core 文档中已经记录了一些内容
-
在单例中使用作用域服务是托管服务的常见问题,因此在 Consuming a scoped service in a Background task 的后台服务文章中对此进行了记录。您将
IServiceProvider传递给您的单例并显式使用CreateScope创建一个范围,然后使用该范围对象创建例如DbContext 实例 -
请检查更新@Andy
标签: c# .net-core memorycache