深入观察 .NET组件模型及继承
现在通过使用嵌入式串化器,我们已经生成语句,必须修改它。直到现在,语句集合包括一个表示法,此表示法代表下面的代码行:
this.model = new Mvc.Components.Model.PublisherModel(this.components);如果根据CodeDom表示法分析它就会发现它有下面的窗体:
• CodeAssignStatement: the = operation, 有左右两部分
• CodeObjectCreateExpression: the right part of the assignment. 指定赋值的右边部分
• CodeFieldReferenceExpression: 表示法Parameters集合中的第一个参数,此参数指向this.components领域。
我们只需要代替或者补充那个参数。
CodeAssignStatement assign = (CodeAssignStatement) statements[0];我们那可以安全地传递CodeThisReferenceExpression,因为包含构件的基本类型实现IContainer,这正是构造函数超载期待完成的。
//The expression at the right is the actual constructor call.
CodeObjectCreateExpression create = (CodeObjectCreateExpression)
assign.Right;
if (create.Parameters.Count > 0)
{
create.Parameters[0] = new CodeThisReferenceExpression();
}
else
{
create.Parameters.Add(new CodeThisReferenceExpression());
}
return statements;
}
}
直到现在,除了ExpandableObjectConverter和被扩展属性,没有提供任何与集成开发环境的集成。让我们看一下怎样提高设计时期经验。
深层集成开发环境集成
到目前为止,在有些方面的实现仍然很薄弱:
• . 在属性浏览器内,被扩展属性内部映射值所作的改变不会总是马上被保存(有些时候它们根本没有被保存)
• 一个可视构件被重新命名,我们失去所有的视图映射,因为它们被储存在ConfiguredViews表(此ConfiguredViews表是建立在它的名称的基础上的)中。同样的,此构件被删除时,映射不会相应地从那个表中被删除。
• 当控制器不是根组件时,一些属性不应该出现在属性浏览器汇总(甚至在)Intellisense中),例如控制器 Components,或者是ConfiguredViews。
• 一个控制器可能需要访问一个DB 连接。如果它支持web.config-bindable 属性或者EXEs 中的app.config 那就非常好。
• 键入控件和模式属性名称,而且模式名称是易于出错的。
• 如果需要很多控件, 通过控件来设置视图映射控件可能非常麻烦。
• 没有办法马上检查所有被应用映射。
集成开发环境无法知道ViewInfo对象属于控制器构件,当对象改变时,必须再次马上串行化它,这就是第一个问题带来的后果。完成这一任务的一个方法就是修改所有属性的设值函数,因此它们能引起的某种事件,可以将事件限制在包含的控制器中。尽管这是一个更加有效的方案,它要求输写代码,通知对每一个属性设值函数所做出的改变,而且它还要求.NET给我们提供一个更好的方法
在集成开发环境内部,所有属性对构件的改变都是通过所谓的描述符来执行的,这是System.ComponentModel.PropertyDescriptor类型的实例。对通过属性浏览器而被应用的改变来说,这一点是非常正确的。事实上,许多控件和Windows Forms绑定机制使用这个方法。通过把System.Windows.Forms.dll IL代码和ILDasm工具倾印起来,以及操作搜索PropertyDescriptor::SetValue,你可以核对检查
0
相关文章