C# 程序中 对象所处的上下文环境

来源:互联网 发布:手机号码归属地数据库 编辑:程序博客网 时间:2024/05/16 13:55

C# 程序中 对象所处的上下文环境

 

 

起因:

近来,我在业余时间忙于开发一个 网站后台自动生成软件——软件的设计开发起因会有另外的文章进行介绍;

现在是 2011-1-154:40   (我已经累计有 超过 13个夜晚都是奋战到这个时候的——为了这个软件);

软件的架构思路,参照公司的标准产品 SUF6.1 的架构模式;

 

最完美的是,该软件支持 插件扩展——任何人相对软件的扩展,都不需要修改源代码——只需要标注特性,那么程序就会加载你的 第三方 工具栏,右键菜单 等选项;

 

                              问题的起因就在插件这一块!

 

我在软件的主体部分通过接口BaseFile, IPageType

创建了一个 插件中的对象

EditPageType      e.aspx

ListPageType      l.aspx

右键单击这个 对象节点,

“文件属性”——这个数据来自 主程序的实现;

“配置窗体”——这个来自 插件 WebCreate.Forever.dll

 

 

然后,我将程序序列化保存,然后再反序列化——结果,这个 节点的 “配置窗体”不见了;

 

这个对象是否可以使用这个 右键菜单项 有一个 判断函数

——这段代码是说,如果 WebObject(网站对象) 不为空,且 这个对象是 插件的 EditPageType 类,那么就表示这个对象可以 使用这个  右键菜单项 ,返回 True(真);

 

 

查错:

 

这个右键菜单去哪了?为什么不显示这个菜单?

——后来查错原因,代码行是

 

我调试了一哈,但是 obj 明显就是 EditPageType 的数据结构,没理由这个代码返回在False啊!

 

于是我写下这行代码,进行强行转换!

结果,我遇到了一个以前都没有遇到的异常:

之后在一个form上使用这个控件,打开这个控件的属性修改NumRange属性,Ctrl+S保存的时候会报错
报错内容为:
Code generation for property 'NumRange' failed. Error was:'[A]WinForm.NumberScope cannot be cast to [B]WinForm.NumberScope. Type Aoriginates from 'WinForm, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null' in the context 'LoadNeither' at location'C:\Users\CHUNSIBO\AppData\Local\Microsoft\VisualStudio\10.0\ProjectAssemblies\elgwjxaa01\WinForm.exe'.Type B originates from 'WinForm, Version=1.0.0.0, Culture=neutral,PublicKeyToken=null' in the context 'LoadNeither' at location'C:\Users\ss\AppData\Local\Microsoft\VisualStudio\10.0\ProjectAssemblies\ko-pdm2_01\WinForm.exe'.'

  ——简单的说,这异常的 意思是说 :

ListPageType  对象  l.aspx  不是  ListPageType;

——这就好比说   人类  的对象 不是 人类  一样;

 

不过,这个异常也很清楚:他的意思也很明确,这个 ListPageType和 ListPageType  是不一样的;

 

我最后仔细思考,明白了原因:这个对象的创建 是 在 主程序中创建的;

而现在,我想在  插件 的方法中转换 主程序的 对象,这时就出错了;

 

比方说:每个人都有身份证;

舒小龙也有一个 身份证,我们可以说的身份证 是 身份证;

但是有一天,去了美国 ,这时 的身份证 是 身份证 美国就不承认这句话是对的了;

舒小龙强行转换,硬是要说这个身份证是身份证——于是美国的工作人员就报了一个异常:这个 身份证 和 身份证 是不一样的;

 

问题的症结在于 上下文环境 的不一样:中国 和 美国;

就像上面说的,创建对象是说 主程序的环境 Default 中创建,但是我想 在LoadNeither 环境下使用他一样!!

 

解决方案:

 

我之前的 WebObject  类是 继承Iserializable——准备进行手动序列化的,但是后来 我觉得手动序列化很麻烦,包括子类都难以幸免;所以,我又取消了这计划;

——如果,手动序列化能不能 避免这个问题呢?

我没有尝试这个,因为;昨晚好不容易将手动序列化的 代码 改成 系统的序列化,我再反一次,我岂不是有病;

 

第二个想法:既然问题出在:Default 中创建,就不能在LoadNeither 中使用;

那么,能不能将 创建的过程 也转移到 插件中,就是  LoadNeither 环境中?

——不可能,因为创建的过程有很多界面在联动工作,主程序是最需要数据的地方,数据的创建如果转移到了 插件中,那么失去这个插件,主程序就会崩溃!且 以后另外的插件 在 主程序中找不到 公共部分,那么岂不是 其他的插件也要 重新编写 创建数据的编码?

 

那么能不能将 插件 的环境 弄得 和 主程序 一样呢?

那样,主程序 和 插件 都能够共享数据,不会有 环境限制;

——是的,这才是最好的办法,最简单,最省力!且依然维护了软件最初的架构设计初衷!

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

话说回来,我的插件 是在 程序的 最开始就执行加载的——加载参数在 配置文件中!

代码简化如下:

——也就是将  WebCreate.Forever.dll  WebCreate.Action.dll  这两个插件加载到程序中;

但是,没想到,系统加载这两个插件程序集时,居然将这两个放到了 别的环境下;——典型的歧视!

 


如何让系统加载这两个程序集时,将其 划归到 默认环境下呢?

我突然想起了 彬哥(我们项目经理)之前的一篇文章可能涉及如何加载程序集;

 

 

——原来 加载程序集的方法有这么多;

我试了一下,结果 正确的做法 正是 第一种:

Assembly.Load("WebCreate.Action");   Assembly.Load("WebCreate.Forever");

 

不过 加载的是 程序集的 命名空间,而不是程序集名称,应该只是当时彬哥写文章时的一个表示而已;

 

好了,问题就此解决!

 

 

感想:

今天的异常 是我一直写程序 所没有遇到过的,很兴奋!

所以,先将程序放下来,写下这篇感想与领悟!