C# 每种类型的静态缓存

C# 每种类型的静态缓存,c#,entity-framework,caching,static,authorization,C#,Entity Framework,Caching,Static,Authorization,我正在寻找一种在基类型上缓存通过反射创建的方法的方法 public class AuthorizedDbContext : DbContext { Dictionary<Type, MethodInfo> _filterMap; DbAuthorizationOptions _authOptions; public AuthorizedDbContext(DbContextOptions options) : base(options) {

我正在寻找一种在基类型上缓存通过反射创建的方法的方法

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容器


这似乎是一个常见的问题,是否有人有一种在程序生命周期内缓存对象的好方法?

您可以在基类中保存一个类型为和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将返回派生最多的类型

我以前也想过这样做,所以+1,我想要比这更干净一点的东西,但我可能会发现这是唯一的办法。@johnny5,我真的想不出别的办法了。我想推荐使用,但这只是向对象添加动态功能,在您的情况下,您需要它用于类型I可能只是在DI中创建一个单例,它将集中我的缓存,但我不想将其作为依赖项,所以我想我将使用您提供的方式