我正在寻找一种方法来缓存我通过反射创建的方法,基类型
public class AuthorizedDbContext : DbContext
{
Dictionary<Type, MethodInfo> _filterMap;
DbAuthorizationOptions _authOptions;
public AuthorizedDbContext(DbContextOptions options) : base(options)
{
}
protected Dictionary<Type, MethodInfo> CreateGenericFilterMap()
{
var genericFilterCache = new Dictionary<Type, MethodInfo>();
foreach (var entityType in this.Model.GetEntityTypes().Select(e => e.ClrType))
{
var genericMethod = typeof(QueryFilterExtensions).GetExtensionMethodFor(typeof(DbContext))
.Where(x => x.Name == nameof(QueryFilterExtensions.Filter))
.Where(x => x.IsGenericMethod && x.IsGenericMethodDefinition)
//TODO switch this to single and filter properly
.First();
genericFilterCache[entityType] = genericMethod.MakeGenericMethod(entityType);
}
return genericFilterCache;
}
}
我有这个方法CreateGenericFilterMap()
,它根据现有的实体类型生成一般过滤的函数。由于AuthorizedDbContext是基类,因此无法静态存储这些方法。
我正在考虑将它们添加到ServicesContainer中以便我可以请求它们,但我不确定这是否正确,因为您不想直接使用DI容器。
这似乎是一个常见问题,是否有人有一个很好的方法来缓存程序生命周期中的对象?
答案 0 :(得分:1)
您可以在基类中保存类型和filterMaps的私有静态字典。如下所示:
public class AuthorizedDbContext : DbContext
{
Dictionary<Type, MethodInfo> _filterMap;
DbAuthorizationOptions _authOptions;
private static Dictionary<Type, Dictionary<Type, MethodInfo>> _cache;
static AuthorizedDbContext() => _cache = new Dictionary<Type, Dictionary<Type, MethodInfo>>();
public AuthorizedDbContext(DbContextOptions options) : base(options)
{
}
protected Dictionary<Type, MethodInfo> CreateGenericFilterMap()
{
var genericFilterCache = new Dictionary<Type, MethodInfo>();
foreach (var entityType in this.Model.GetEntityTypes().Select(e => e.ClrType))
{
var genericMethod = typeof(QueryFilterExtensions).GetExtensionMethodFor(typeof(DbContext))
.Where(x => x.Name == nameof(QueryFilterExtensions.Filter))
.Where(x => x.IsGenericMethod && x.IsGenericMethodDefinition)
//TODO switch this to single and filter properly
.First();
genericFilterCache[entityType] = genericMethod.MakeGenericMethod(entityType);
}
return _cache[GetType()] = genericFilterCache;
}
public Dictionary<Type, MethodInfo> GetCache() => _cache[GetType()];
}
这将有效,因为 GetType 将返回最派生的类型。