using Microsoft.AspNetCore.Http; using System; using System.Linq.Expressions; using System.Reflection; using System.Threading; namespace Znyc.Admin.Commons.Core.App { /// /// 获取 HttpContext 上下文 /// public static class HttpContextLocal { private static Func _asyncLocalAccessor; private static Func _holderAccessor; private static Func _httpContextAccessor; /// /// 获取当前 HttpContext 对象 /// /// public static HttpContext Current() { object asyncLocal = (_asyncLocalAccessor ??= CreateAsyncLocalAccessor())(); if (asyncLocal == null) { return null; } object holder = (_holderAccessor ??= CreateHolderAccessor(asyncLocal))(asyncLocal); if (holder == null) { return null; } return (_httpContextAccessor ??= CreateHttpContextAccessor(holder))(holder); // 创建异步本地访问器 static Func CreateAsyncLocalAccessor() { FieldInfo fieldInfo = typeof(HttpContextAccessor).GetField("_httpContextCurrent", BindingFlags.Static | BindingFlags.NonPublic); MemberExpression field = Expression.Field(null, fieldInfo); return Expression.Lambda>(field).Compile(); } // 创建常驻 HttpContext 访问器 static Func CreateHolderAccessor(object asyncLocal) { Type holderType = asyncLocal.GetType().GetGenericArguments()[0]; MethodInfo method = typeof(AsyncLocal<>).MakeGenericType(holderType).GetProperty("Value").GetGetMethod(); ParameterExpression target = Expression.Parameter(typeof(object)); UnaryExpression convert = Expression.Convert(target, asyncLocal.GetType()); MethodCallExpression getValue = Expression.Call(convert, method); return Expression.Lambda>(getValue, target).Compile(); } // 获取 HttpContext 访问器 static Func CreateHttpContextAccessor(object holder) { ParameterExpression target = Expression.Parameter(typeof(object)); UnaryExpression convert = Expression.Convert(target, holder.GetType()); MemberExpression field = Expression.Field(convert, "Context"); UnaryExpression convertAsResult = Expression.Convert(field, typeof(HttpContext)); return Expression.Lambda>(convertAsResult, target).Compile(); } } } }