每种类型的静态缓存

时间:2018-01-05 16:55:15

标签: c# entity-framework caching static authorization

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

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

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

1 个答案:

答案 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 将返回最派生的类型。