CommunityServer读取Blog分析(一)

 

首选,会建立 AggregatePostList 类的一个实例,先执行 AggregatePostList 类的构造函数,并执行类中有赋初值的所有语句,因为 AggregatePostList 是继承于 WeblogBaseTemplatedWebControl 类,而 WeblogBaseTemplatedWebControl 类又继承于 TemplatedWebControl 类,而 TemplatedWebControl 类又继承于 WebControl 类,且实现 INamingContainer 接口,所以,严格的说应该一开始是执行这四个类的构造函数(默认的构造函数,即没有参数的构造函数)和这四个类中所有有赋初值的语句。且执行顺序是从基类开始!好,第一个,WebControl的构造函数,输出HTML元素<span id=”xxx”></span>,接下来看 TemplatedWebControl 类,该类没有构造函数,再接着看 WeblogBaseTemplatedWebControl 类的构造函数,只有一句:

_currentUser = CSContext.Current.User;

获取当前浏览者的各方面信息,详细见 CommunityServer.Components.User 类。

最后看 AggregatePostList 类的构造函数,哈,空的,过!

在这个过程中,要注意各类中赋初值的语句,因为有一些信息不知不觉已经初始化,而在后面分析代码却不知是从何而来。

接下来,应该转到 AggregatePostList 类的 OnLoad 函数,第一句:

base.OnLoad(e);

此方法通知服务器控件应执行关联页的每个 HTTP 请求的共同操作,例如设置数据库查询。在页生存期的此阶段,创建并初始化层次结构中的服务器控件,还原视图状态,并且窗体控件反映客户端数据(这一段理解不是很深,不敢多写)。下一句:

this.EnsureChildControls();

EnsureChildControls 函数是System.Web.UI.Control类的一个protected virtual void 方法(虚拟方法,提供默认实现)。代码如下:

protected virtual void EnsureChildControls()

{

      if (!this.ChildControlsCreated && !this.flags[0x100])

      {

            this.flags.Set(0x100);

            try

            {

                  this.ResolveAdapter();

                  if (this._adapter != null)

                  {

                        this._adapter.CreateChildControls();

                  }

                  else

                  {

                        this.CreateChildControls();

                  }

                  this.ChildControlsCreated = true;

            }

            finally

            {

                  this.flags.Clear(0x100);

            }

      }

}

MSDN

功能:确定服务器控件是否包含子控件。如果不包含,则创建子控件。

该方法首先检查 ChildControlsCreated 属性的当前值。如果此值为假,则调用 CreateChildControls 方法。其中:

ChildControlsCreated 属性:设置或指示是否已创建服务器控件的子控件。

CreateChildControls 方法:一个 virtual(虚拟)方法,没提供默认实现,一般由开发复合服务器控件或模板服务器控件的用户重写此方法,用于创建自定义控件的子控件。WebControl 类没有重新此方法,那么其它三个类()中必定有一个重写此方法。确实,在 TemplatedWebControl 类就有如下的定义:

protected override void CreateChildControls()

{

Controls.Clear();

 

// 1) String Control

Boolean _skinLoaded = LoadTextBasedControl();

 

// 2) Inline Template

if ( !_skinLoaded )

{

_skinLoaded = LoadSkinTemplate();

}

 

// 3) Themed Control

if (!_skinLoaded)

{

_skinLoaded = LoadThemedControl();

}

 

// 4) Default Control

if ( !_skinLoaded )

{

_skinLoaded = LoadDefaultThemedControl();

}

 

// 5) If none of the skin locations were successful, throw.

if ( !_skinLoaded )

{

throw new CSException( CommunityServer.Components.CSExceptionType.SkinNotFound, this.GetType().ToString() );

}

 

if(_skinLoaded)

     AttachChildControls();

}

上面说了,CreateChildControls 方法是创建自定义控件的子控件(在此是某个 Web 用户控件)。首先,执行 Controls.Clear() 方法,从当前服务器控件的 ControlCollection 对象中移除所有控件。接着根据不同情况,调用不同的方法创建不同的控件,这些方法都以Load开头,每个方法都被设计为虚拟(virtual)方法。首先是LoadTextBasedControl() 方法,代码如下:

protected virtual bool LoadTextBasedControl()

{

string text = ControlText();

if(!Globals.IsNullorEmpty(text)) // text 为空或为 null IsNullorEmpty 方法返回真。

{//有指定 Web 用户控件名称

Control skin = this.Page.ParseControl(text);

skin.ID = "_";

this.Controls.Add(skin);

return true;

}

return false;

}

首先,执行 ControlText() 方法,该方法也被设计为虚拟方法,且默认实现是返回 null,代码如下:

protected virtual string ControlText()

{

return null;

}

为什么要这样做呢?我认为是为了有更好的扩展性,如:我们要创建的 Web 用户控件的名称需要从数据库读取,那么就可以重写 ControlText() 方法,然后在 ControlText() 方法中从数据库读出并返回控件名称,或通过在 ControlText() 方法用其它方法返回控件名称。在此例,LoadTextBasedControl() 方法返回 false。而一旦调用某个方法创建好子控件后,其它情况将被忽略,直至调用 AttachChildControls() 方法。好,接下来分析调用 LoadSkinTemplate() 方法的情况,当用户控件有出现模板化属性的情况下将会调用 LoadSkinTemplate() 方法,模板的名称和用户控件的类的属性相关联,如 TemplatedWebControl 类就以下定义

 

public ITemplate SkinTemplate

{

get

{

return _skinTemplate;

}

set

{

_skinTemplate = value;

ChildControlsCreated = false;

}

}

private ITemplate _skinTemplate;

 

说明 SkinTemplate 就是一个模板属性,在页面中就可以如下引用:

<Blog:AggregatePostList runat="Server" id="Aggregatepostlist1" NAME="Aggregatepostlist1" EnablePaging="true">

<SkinTemplate>

Server control, data-binding syntax, other valid markup

</SkinTemplate>

</Blog: AggregatePostList>

 

 

 

posted @ 2006-08-11 14:32  pcvc  阅读(433)  评论(0编辑  收藏  举报