首页 > 其他分享 >blog.core MemoryCacheExtensions 为空处理

blog.core MemoryCacheExtensions 为空处理

时间:2024-12-03 10:44:53浏览次数:9  
标签:core cache Value blog BindingFlags typeof 为空 new static

using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
using Microsoft.Extensions.Caching.Memory;

namespace Blog.Core.Common.Caches.Extensions;

public static class MemoryCacheExtensions
{
    #region Microsoft.Extensions.Caching.Memory_6_OR_OLDER

    private static readonly Lazy<Func<MemoryCache, object>> GetEntries6 = new(() =>
        (Func<MemoryCache, object>)Delegate.CreateDelegate(typeof(Func<MemoryCache, object>),
            typeof(MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance)
              ?.GetGetMethod(true) ?? throw new InvalidOperationException("Cannot find property 'EntriesCollection' on MemoryCache."),
            throwOnBindFailure: true));

    #endregion

    #region Microsoft.Extensions.Caching.Memory_7_OR_NEWER

    private static readonly Lazy<Func<MemoryCache, object>> GetCoherentState7 = new(() =>
        CreateGetter<MemoryCache, object>(typeof(MemoryCache)
           .GetField("_coherentState", BindingFlags.NonPublic | BindingFlags.Instance)));

    private static readonly Lazy<Func<object, IDictionary>> GetEntries7 = new(() =>
        CreateGetter<object, IDictionary>(typeof(MemoryCache)
           .GetNestedType("CoherentState", BindingFlags.NonPublic)?
           .GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance)));

    #endregion

    #region Microsoft.Extensions.Caching.Memory_8_OR_NEWER

    private static readonly Lazy<Func<MemoryCache, object>> GetCoherentState8 = new(() =>
        CreateGetter<MemoryCache, object>(typeof(MemoryCache)
           .GetField("_coherentState", BindingFlags.NonPublic | BindingFlags.Instance)));

    private static readonly Lazy<Func<object, IDictionary>> GetEntries8 = new(() =>
        CreateGetter<object, IDictionary>(typeof(MemoryCache)
           .GetNestedType("CoherentState", BindingFlags.NonPublic)?
           .GetField("_stringEntries", BindingFlags.NonPublic | BindingFlags.Instance)));

    
    #endregion

    private static Func<TParam, TReturn> CreateGetter<TParam, TReturn>(FieldInfo field)
    {
        if (field == null)
        {
            return null;
            throw new ArgumentNullException(nameof(field), "Field cannot be null.");
        }

        var methodName = $"{field.ReflectedType!.FullName}.get_{field.Name}";
        var method = new DynamicMethod(methodName, typeof(TReturn), new[] { typeof(TParam) }, typeof(TParam), true);
        var ilGen = method.GetILGenerator();
        ilGen.Emit(OpCodes.Ldarg_0);
        ilGen.Emit(OpCodes.Ldfld, field);
        ilGen.Emit(OpCodes.Ret);
        return (Func<TParam, TReturn>)method.CreateDelegate(typeof(Func<TParam, TReturn>));
    }
    //TODO,服务器上用的是net8,却用要GetEntries7。这边判断是否为空,不为空用GetEntries7,为空用GetEntries8
    private static readonly Func<MemoryCache, IDictionary> GetEntries = cache =>
    {
        if (GetEntries7.Value != null)
        {
            return GetEntries7.Value(GetCoherentState7.Value(cache));
        }
        else
        {
            return GetEntries8.Value(GetCoherentState8.Value(cache));
        }
    };
    //TODO,服务器上用的是net8,却用要GetEntries7.
    //private static readonly Func<MemoryCache, IDictionary> GetEntries =
    //    Assembly.GetAssembly(typeof(MemoryCache))?.GetName().Version?.Major switch
    //    {
    //        < 7 => cache => (IDictionary)GetEntries6.Value(cache),
    //            _ => cache => GetEntries7.Value(GetCoherentState7.Value(cache)),  //发布服务器用这个版本
    //         //7 => cache => GetEntries7.Value(GetCoherentState7.Value(cache)),
    //         //_ => cache => GetEntries8.Value(GetCoherentState8.Value(cache)),
    //    };

    public static ICollection GetKeys(this IMemoryCache memoryCache) =>
        GetEntries((MemoryCache)memoryCache).Keys;

    public static IEnumerable<T> GetKeys<T>(this IMemoryCache memoryCache) =>
        memoryCache.GetKeys().OfType<T>();
}

 

标签:core,cache,Value,blog,BindingFlags,typeof,为空,new,static
From: https://www.cnblogs.com/handsomeziff/p/18583585

相关文章

  • 如何备份 Z-BlogPHP 数据库和文件?
    备份Z-BlogPHP的数据库和文件是非常重要的,尤其是在进行升级或重大更改之前。备份数据库的步骤如下:备份数据库:使用phpMyAdmin或其他数据库管理工具,导出你的Z-BlogPHP数据库。选择导出格式为SQL文件,并保存到安全的位置。备份文件:通过FTP或SFTP客户端,下载Z-Bl......
  • 如何在 Z-BlogPHP 中进行系统升级?
    在Z-BlogPHP中进行系统升级是一个简单而重要的过程,确保你的博客始终运行在最新版本,以获得最新的功能和安全更新。以下是详细的升级步骤:进入后台管理:登录Z-BlogPHP后台管理界面,使用你在安装时设置的管理员用户名和密码。访问应用中心:在后台管理界面中,找到并点击“应......
  • 在进行空间迁移时,如何修改 Z-BlogPHP 的配置文件?
    在进行空间迁移时,修改Z-BlogPHP的配置文件 c_option.php 是一个关键步骤,确保你的博客在新服务器上能够正常运行。以下是详细的步骤和注意事项:备份原文件:在修改配置文件之前,务必备份原文件。可以通过FTP或SFTP下载 c_option.php 文件到本地计算机,确保在修改过程中出......
  • 如果 Z-BlogPHP 版本低于 1.6.0,如何开启固定域名功能?
    如果你的Z-BlogPHP版本低于1.6.0,直接使用 ZC_PERMANENT_DOMAIN_FORCED_URL 配置项可能不起作用,因为这个配置项是在1.6.0及之后的版本中引入的。为了在低版本中实现固定域名功能,你需要采取以下步骤:步骤备份现有文件:在进行任何修改之前,建议备份现有的 zb_system 文件......
  • ASP.NET Core 9.0 中新增的MapStaticAssets() 中间件
    前言在Core9.0版本中新增的内容不算多,除了内置OpenAPI外应该就属MapStaticAssets中间件最有价值了,最初MapStaticAssets主要是为了解决Blazor静态资源加载缓慢而生的,当然只要是wwwroot下的任何静态资产都是可以使用TA平替UseStaticFiles的,因此在了解了TA的优势后建议升级......
  • 面对api-ms-win-core-console-l1-2-0.dll丢失怎么处理?dll找不到的解决方法
    api-ms-win-core-console-l1-2-0.dll是Windows操作系统中的一个动态链接库文件,它属于Microsoft的WindowsAPI集的一部分。这个DLL文件主要负责提供与控制台相关的功能支持。当用户尝试运行某些应用程序时遇到此文件丢失或损坏的错误提示,通常会导致程序无法正常启动。......
  • 基于.NetCore开发博客项目 StarBlog - (32) 第一期完结
    前言本文记录一下StarBlog项目的当前状态与接下来v2版本的开发规划。StarBlog项目从2022年开始至今已经2年多了,本来早就该给第一期做个小结的,但这种博客类型的项目,一旦稳定能用之后,我就没多大的动力去更新了......
  • AI之旅:Microsoft.Extensions.AI 送惊喜,Cnblogs.DashScope.AI 表支持
    https://www.cnblogs.com/cmt/p/18577574 2024年10月8日,微软.NET官方博客发布了一篇博文 IntroducingMicrosoft.Extensions.AIPreview–UnifiedAIBuildingBlocksfor.NET,给.NET开发者带来了一个小惊喜,.NET类库将增加一个统一的调用AI服务的抽象接口层。Mic......
  • 如何判断一个对象是否为空?
    在前端开发中,判断一个对象是否为空的方法取决于你想判断的是哪种“空”。以下几种情况和对应的判断方法:1.判断对象是否为空对象(没有任何属性):这是最常见的“空对象”的定义。一个空对象{}不包含任何自有属性。Object.keys():这是最推荐的方法,因为它简洁明了且兼容性好。......
  • zblog 获取全部分类列表函数 GetCategoryList 的参数和使用方法介绍
    函数参数$select (数组):获取指定数据。$where (数组):数据获取限制规则。$order (数组):数据获取排序规则。$limit (数组):获取数据数量限制。$option (数组):附加限制选项,可用来获取指定范围内的数据。函数输出输出一个数组,包含分类列表数据。示例代码{foreach......