今天在做架构的过程中,遇到这样的一个问题:单建的实例不见了!
真的很奇怪,整整一个下午,想了无数的方法,做了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分钟就搞定了。但是究竟发生了什么???有空再研究研究。