日期:2014-05-17  浏览次数:21031 次

单建的实例哪里去了?【Asp.Net MVC4】

今天在做架构的过程中,遇到这样的一个问题:单建的实例不见了!

真的很奇怪,整整一个下午,想了无数的方法,做了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应用程序下就没有问题,而就是在网站项目下失效了。

故障原因虽然找到了,但是为什么会这样就不太明白了。