Castle动态代理缓存切面:运行时类型转换异常求助
解决方案
1. 核心问题分析
你遇到的两个类型不匹配问题本质是:
- 直接调用
Task.FromResult(cachedValue)会生成Task<object>,但被拦截方法返回的是Task<T>(T为运行时确定的具体类型),导致类型转换失败。 - 缓存反序列化返回的是具体实现类(如
List<MovieResponse>),但方法声明返回接口/父类型(如IEnumerable<MovieResponse>),直接赋值会引发类型转换异常。
2. 修复后的代码实现
public class CacheAspect : MethodInterception { private readonly int _duration; private readonly string _key; private readonly ICacheService _cacheService; public CacheAspect(string key, int duration) { _key = key; _duration = duration; _cacheService = ServiceTool.ServiceProvider.GetService<ICacheService>(); } public override async void Intercept(IInvocation invocation) { // 获取被拦截方法返回的Task<T>中的泛型参数T var resultType = invocation.Method.ReturnType.GetGenericArguments()[0]; var cachedValue = _cacheService.Get(_key, resultType); if (cachedValue is not null) { // 处理具体类型到接口/父类型的转换(如List转IEnumerable) object convertedValue; try { convertedValue = Convert.ChangeType(cachedValue, resultType); } catch (InvalidCastException) { // 转换失败时 fallback 到原方法执行 invocation.Proceed(); var returnValue = await (dynamic)invocation.ReturnValue; _cacheService.Add(_key, returnValue, TimeSpan.FromHours(_duration)); return; } // 通过反射创建正确泛型类型的Task<T>,避免Task<object>类型不匹配 var fromResultMethod = typeof(Task).GetMethod(nameof(Task.FromResult)) .MakeGenericMethod(resultType); invocation.ReturnValue = fromResultMethod.Invoke(null, new[] { convertedValue }); return; } // 缓存未命中时执行原方法并缓存结果 invocation.Proceed(); var returnValue = await (dynamic)invocation.ReturnValue; _cacheService.Add(_key, returnValue, TimeSpan.FromHours(_duration)); } }
3. 关键逻辑说明
- 动态创建泛型Task:通过反射获取
Task.FromResult<T>的泛型版本,传入转换后的缓存值,生成与被拦截方法返回类型完全一致的Task<T>,解决Task<object>转Task<IEnumerable<T>>的异常。 - 类型转换处理:
Convert.ChangeType支持引用类型的向上转换(如实现类转接口),确保缓存值类型与方法声明的返回类型匹配,解决List<T>转IEnumerable<T>的异常。
4. 可选优化建议
- 替换
async void:async void是异步编程的不良实践,容易导致未捕获异常。如果你的Castle版本支持,建议改用IAsyncInterceptor实现异步拦截,更符合异步编程规范。 - 缓存序列化优化:在反序列化时,可以尝试直接将JSON序列化为接口对应的代理类型,但需要自定义JsonConverter,不过上述代码的转换逻辑已能覆盖大部分场景。
内容的提问来源于stack exchange,提问作者Canberk
相关产品推荐
相关产品推荐

