異常描述
最近使用Redis發現了一個十分詭異的異常,異常如下:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: “StackExchange.Redis.IBatch”未包含“HashSetAsync”的定義
在 CallSite.Target(Closure , CallSite , IBatch , String , String , Object )
在 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid4[T0,T1,T2,T3](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
在 DbCommandExecutor.RunCommand(RedisCmd cmdInfo, Boolean isMutiWrite)
原因分析
乍一看,似乎是引用的類庫存在問題,不包含HashSetAsync的定義,但通過dotPeek反編譯發現“HashSetAsync”方法是確實存在的,並非問題所在,再仔細查看RuntimeBinderException產生的原因有兩種:
- 第一種:'Microsoft.CSharp.RuntimeBinder.Binder' is not defined or imported,該異常是由於
Microsoft.CSharp
引用缺失導致,直接引用即可; - 第二種:是因爲匿名類型不能跨程序集,需要在源程序集中引入
[assembly: InternalsVisibleTo("XXX.XXX.XXX")]
分析代碼發現,因爲某些不可描述的原因,我使用了dymaic類型:
/// <summary>
/// Redis執行參數。
/// </summary>
public class RedisParam
{
/// <summary>
/// Redis 鍵。
/// </summary>
public string Key { get; set; }
/// <summary>
/// Redis 複合結構中的鍵。
/// </summary>
public string StructKey { get; set; }
/// <summary>
/// 數據結構中的值。
/// </summary>
public dynamic StructVal { get; set; }
}
不過RedisHash本身就是一個string類型的field和value的映射表,略做調整,並把dynamic改爲string,算是解決了,這個問題本身涉及到了本人的知識盲區和設計上的失誤導致的,小計一筆,避免再犯。