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