即使根组件是Base控制器本身时,仍然会调用串化器,意识到这一点非常重要。在这种情况下,我们没必要维持自定义代码,因为当它被用于另一个构件内部时(例如:一个Page或者一个Form),它主要用于基础方面。为了考虑这个问题,我们要求使用先前用过的IDesignerHost服务,核对它的RootComponent属性。IDesignerSerializationManager实现IServiceProvider,因此我们用通常的GetService方法来完成它。
IDesignerHost host = (IDesignerHost)当序列化/反序列化代码时,基本CodeDomSerializer类型可以和一些有用的方法一起合作。访问ConfiguredViews属性时,通过正在运行(value参数)的实际控制器的引用来完成这一过程。基本类型里的一个帮助方法创建正确的CodeDom对象,在CodeDom图表中,使用这个引用。
manager.GetService(typeof(IDesignerHost));
if (host.RootComponent == value)
return statements;
CodeExpression cnref = SerializeToReferenceExpression(manager, value);现在可以利用CodeExpression来创建属性引用。
CodePropertyReferenceExpression propref =我们主要定义两个变量,简化下面将建立的一个表示法,再次看一下样本目标方法调用:
new CodePropertyReferenceExpression(cnref, "ConfiguredViews");
controller.ConfiguredViews.Add("txtID",
new ViewInfo("txtID", "Text", "Publisher", "ID"));
我们已经为ConfiguredViews属性访问建立了第一部分,接下来的部分就是: • CodeMethodInvokeExpression: Add的调用
• CodeExpression[]: 方法调用的参数.
• CodePrimitiveExpression: "txtID" 元字符串值.
• CodeObjectCreateExpression: 新的 View Info 部分.
• CodePrimitiveExpression:被传递到构造函数的每一个元字符串值
因此代码就是:
Collapse注意:正确缩排在制定更加可读的语句方面能怎样提供帮助。顺便提一下,现在仅仅声明了两个临时变量,这两个临时变量也可以省略。
BaseController cn = (BaseController) value;
CodeExpression cnref = SerializeToReferenceExpression(manager, value);
CodePropertyReferenceExpression propref =
new CodePropertyReferenceExpression(cnref, "ConfiguredViews");
//Iterate the entries
foreach (DictionaryEntry cv in cn.ConfiguredViews)
{
ViewInfo info = (ViewInfo) cv.Value;
if (info.ControlID != String.Empty && info.ControlProperty != null &&
info.Model != String.Empty && info.ModelProperty != String.Empty)
{
//Generates:
//controller.ConfiguredViews.Add(key, new ViewInfo([values]));
statements.Add(
new CodeMethodInvokeExpression(
propref, "Add",
new CodeExpression[] {
new CodePrimitiveExpression(cv.Key),
new CodeObjectCreateExpression(
typeof(ViewInfo),
new CodeExpression[] {
new CodePrimitiveExpression(info.ControlID),
new CodePrimitiveExpression(info.ControlProperty),
new CodePrimitiveExpression(info.Model),
new CodePrimitiveExpression(info.ModelProperty) }
) }
));
}
}
我们可以使用下面的,给代码补充注释:
statements.Add(new使用构件,回到窗体,在相关联的InializeComponent章节中,我们可以拥有下面的代码。
CodeCommentStatement("-------- ClariuS Custom Code --------"));
private void InitializeComponent()代码生成程序完全适合所有类型引用,因为不会保证开发者将给类型补充必要的using 句子。
{
...
// ------------- ClariuS Custom Code -------------
this.controller.ConfiguredViews.Add("txtID",
new Mvc.Components.Controller.ViewInfo("txtID",
"Text", "Publisher", "ID"));
this.controller.ConfiguredViews.Add("txtName",
new Mvc.Components.Controller.ViewInfo("txtName",
"Text", "Publisher", "Name"));
...
生成代码时,我们也可以发送找到的错误。例如,如果检查到这些属性建立得不正确,也可以发送找到的错误。
Collapse注意,我们使用其他manager方法,设计错误信息,GetInstance 和GetName允许我们重新找到对象引用以及各自的名称。当找到错误后,通过使用continue能避免无效设置的串行化,有效地删除了无效设置。当此地有无效值时,构件用户可以看到像下面一样得事物:
if (info.ControlID != String.Empty && info.ControlProperty != null &&
info.Model != String.Empty && info.ModelProperty != String.Empty)
{
//Report errors if necessary
object ctl = manager.GetInstance(info.ControlID);
if (ctl == null)
{
manager.ReportError(String.Format("Control '{0}' associated" +
" with the view mapping in " + "controller '{1}' doesn't " +
"exist in the page.", info.ControlID, manager.GetName(value)));
continue;
}
if (ctl.GetType().GetProperty(info.ControlProperty) == null)
{
manager.ReportError(String.Format("Control property '{0}' in" +
" control '{1}' associated " + "with the view mapping in controller" +
" '{2}' doesn't exist.", info.ControlProperty, info.ControlID,
manager.GetName(value)));
continue;
}