今天在做架構的過程中,遇到這樣的一個問題:單建的執行個體不見了!
真的很奇怪,整整一個下午,想了無數的方法,做了N多的測試,可就是找不見。
大致是這樣的情況:
在項目啟動的初期,將一些選項值初始在一個單建的執行個體中,事情很簡單吧?好了,開始實現,一會兒就完成了,建一個控制台程式測試,一切正常。
好了,剛才做的這些事情是一個網站的服務部份。現在開始搭建網站。Asp.Net MVC4,一會兒也好了,測試一下,咦,初始化的單建執行個體的值全部沒有了?
暈呀……
當然我的初始化,用了反射,這樣一系列的單建無需指定,一股腦就全自動初始化了。
下面是實始化的核心代碼部份:
var optionList = new List<ICoderSetting>(); // 遍曆搜尋出來的所有的Option進行執行個體 foreach (Type klass in types) { try { if (klass.IsAbstract) continue; if (klass.FullName != null) { if (!parmsInfoMap.ContainsKey(klass.FullName)) { _Logger.Info(klass.FullName + " 未找到程式員配置的配置資訊,該程式員配置將不被啟用。"); continue; } } //通過單建執行個體靜態屬性的屬性名稱建立該程式員配置 var prop = klass.GetProperty("ME") ?? klass.GetProperty("Instance"); if (prop != null) { var option = (ICoderSetting) (prop.GetValue(null, null)); if (null != option) { // 填充Option類型的Order(排序)屬性 if (klass.FullName != null) if (parmsInfoMap.ContainsKey(klass.FullName)) { XmlElement orderEle = parmsInfoMap[klass.FullName]; if (orderEle.HasAttribute("order")) { int order; if (int.TryParse(orderEle.GetAttribute("order"), out order)) _Logger.Trace(klass.Name + "的排序定義為:" + order); option.Order = order; } } // 將有效Option放入集合中 optionList.Add(option); } } else { _Logger.Warn(string.Format("未找到合適程式員配置的單建執行個體屬性。{0}", klass.FullName)); } } catch (Exception e) { _Logger.Error(string.Format("{0} 程式員配置初始化異常。{1}", klass.FullName, e.Message), e); } } // 按照設定檔中每個程式員配置節點定義的排序值進行排序 optionList.Sort(); // 遍曆所有的Option的執行個體,調用這些Option的初始化方法進行初始化 foreach (ICoderSetting option in optionList) { try { Type type = option.GetType(); MethodInfo method = type.GetMethod(INITIALIZES, (BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance))); // 調用 Initializes(source) 方法, if (type.FullName != null) if (parmsInfoMap.ContainsKey(type.FullName)) method.Invoke(option, new object[] {parmsInfoMap[type.FullName]}); _Logger.Info(string.Format("程式的 {0} 程式員配置類型初始化成功。", type.Name)); _OptionMap.Add(type.Name, option); } catch (Exception e) { _Logger.Error(string.Format("{0} 程式員配置初始化異常。{1}", option.GetType().FullName, e.Message), e); } }
可就是這樣一些代碼,運行雖然正常,可就是丟了資料,丟失了單建執行個體的特徵。但是同一樣的代碼,用了三四年了(這是我專門寫的稱之為“程式員配置”的架構),在WinForm,WPF應用程式下就沒有問題,而就是在網站項目下失效了。
故障原因雖然找到了,但是為什麼會這樣就不太明白了。
解決也容易,換一種設計思路,20分鐘就搞定了。但是究竟發生了什嗎???有空再研究研究。