Saturday, February 17, 2007

TrueLove 项目感悟(三)深入探析 Data Source Control 之一

引言
最近在做 TrueLove 项目的时候用 GridView + ObjectDataSource + NBear 的 Gateways 取得数据就能绑定到一块,按照自己的需要显示到页面上,感觉很神奇。总是想看看在这个交易之下到底有什么发生。这些数据是怎么绑定到一起的,使用了什么机制,一连串的问号。我参考了一部分 MSDN 和其他一些网站的文章,终于弄明白了真个过程,不敢独享,写下来与大家分享。
基类 BaseDataBound
所有使用新的数据源控件绑定数据的数据绑定控件都是从 BaseDataBound 这个类继承下来的。这个类有下面两个 public 的属性。
BaseDataBound 的 public 属性virtual object DataSource { get; set; }
virtual string DataSourceId { get; set; }
还有下面两个模板方法:
Template Methodsprotected abstract void PerformSelect();
protected abstract void ValidateDataSource(object dataSource);
第一个属性 DataSource 是我在 Asp.net 1.1 时代时候绑定数据的。第二个就是我们在 Asp.net 2.0 时代用来绑定 DataSourceControl 的了。如果我们设置了 DataSource 属性之后 ValidateDataSource 方法就会被调用看绑定的数据是不是可以使用(通常判断是不是IListSource, IEnumerable 或 IDataSource 的)。
如果你在初始化阶段之后才改变 DataSourceId 属性的话,那么 DataBind 函数只有在 PreRender 的时候才能被调用,如果你在 PreRender 之后改变的话, DataBind 函数会被立即调用。有一点需要注意的是如果你在 PreLoad 之前设置 DataSourceId 的值,那么 DataBind 函数不会被调用。
下面是 BaseDataBound 类在整个 Asp.net 页面的 Life Cycle 所在的部分:
OnInit: 若ViewState不可用, 那么 Control 会在每次 PreRender 调用.
OnPreLoad: 设置一个内部标志去标识 init 阶段结束.
OnPreRender: 设置一个内部标识标记 PreRender 开始,并且调用 DataBind.
BaseDataBound 类拥有一个 public mothed
Public Mothed public override void DataBind();
这个方法会调用一个模板方法 PerformSelect,PerformSelect 方法会从下面的 DataSource 获取数据。
控件 DataBoundControl
DataBoundControl 是从 BaseDataBound 这个积累继承过来的.DataBoundControl 是所有数据绑定控件的基类。这个类比 BaseDataBound多了一个公共属性:
Public Property public virtual string DataMember { get; set; }
这个属性是在数据源导出多于一个数据列时确定使用那一个数据列。
这个类的主要任务是完成分离从数据源提取出来数据所衍生出来的类。这些从数据源获取的数据在模板方法 PerformDataBinding 中会被看作实现 IEnumerable 接口的派生类集合。
protected internal virtual mothed protected internal virtual void PerformDataBinding(IEnumerable data);
幸运的是最艰难的工作被 ConnectToDataSourceView 方法完成了。这个方法可以获取一个到 DataSourceView 的引用。对于使用 DataSourceId 的控件来说这是一个很大的进步,而对于使用 DataSource 的则需要用一个内嵌类把 DataSource 包装成一个 DataSourceControl (ReadOnlyDataSource实现了 IDataSouce 接口,返回一个只支持 Select方法的 view 对象(ReadOnlyDataSourceView))
下面是整个 DataBoundControl 在 Asp.net 页面的 Life Circle 所占的位置:
OnPreLoad: 如果这个页面是第一次被请求调用基类的 OnPreLoad 方法,如果 ViewState 可用但是 Control 并没有绑定数据,那么设置一个标记试图在 OnPreRender 阶段绑定数据。
OnLoad: 如果没有数据源的 view 则尝试获取,并且在遇到下面这种情况:如果因为某种原因导致我们在 OnPreLoad时候没有尝试绑定数据并且现在仍然没有绑定数据的,设置一个标识,让它尝试在 OnPreRender 的时候绑定数据。
我们看这个类就解决了其基类留下的在 PreLoad 之前的阶段设置 DataSourceId 属性不能自动绑定数据的问题。
如果 Control 使用 DataSourceId 属性来绑定数据,那么 Control 会在数据源变化时捕获 DataSourceView 因重新绑定control 而激活的 DataSourceViewChanged 事件(我会在后续的文章的 DataSourceView 阶段说明的)。
这个类实现了在基类中定义的模板方法 ValidateDataSource 和 PerformSelect 。首先要先检查数据源是不是实现了 IListSource,IEnumerable 或 IDataSource 接口中的一个,如果没有就抛出异常。接着就是被 DataBind 方法调用的 PerformSelect完成下面的:
如果control绑定是通过 DataSource属性则激活DataBinding事件
从数据源获取 DataSourceView
使 control 绑定数据
构造 select 参数,调用 DataSourceView 的 select 方法,传入一个在 select 方法执行完后会被调用的回调方法。
这个方法会在select方法执行完成后调用,在这个方法中调用了 PerformDataBinding 方法,如果还记得他就是那个传入被 IEnumerable 话的数据的方法。
关于 DataSourceControl 和 DataSourceView 的介绍我会在后续的文章中慢慢写。这篇文章主要参考了 Manuel Abadia 的文章,有一些边读边译边体会边写的味道。大家可能看着比较迷惑,我会在后续的文章中说明,并且会画出一个关系调用图。现在正在寻找画图的好工具,不知道大家有没有推荐的。
老婆今天有些感冒,很难受,希望她可以早日康复。老婆的姐姐明天去看房子叫预付款,不知道我们俩什么时候能去买房子,期待 ing ...

TrueLove 项目感悟(二)安全、布局、架构

引言
最近这两天一直没有时间来写这个系列文章。忙着做个 Spider 来抓点东西。我们的 www.365rss.cn 刚刚起步,希望大家多去看看,支持一下。因为好几天前做完的 TrueLove 的这个模块,很多当时遇到的问题都忘记了(悔恨当时没有用笔记下来)。我这里只说说3个我现在能够回忆起来的东西。基于 Form 的安全机制、基于 Div+CSS 的网页布局、基于MVP的架构。下面听我一个部分一个部分的慢慢道来:
基于 Form 的安全机制
其实说到 Asp.net 2.0 的全新的安全模型这些老生长谈的话题我这里也没有必要多少,具体的大家可以参考 MSDN 和下面的这篇文章:ASP.NET 2.0 Membership, Roles, Forms Authentication, and Security Resources 。我这里主要想说的是网站在用到Nbear框架的时候怎么配置使用自己的Roles providers 和 Membership providers,因为如果使用 asp.net 自带的那个数据库的话一个是程序部署不方便,二是他的要求高,添加个用户密码要求巨严格,我是直接受不了。要配置基于 Nbear 数据库链接的 providers 当然必须要先配置 Nbear 的数据库链接。在web.config文件里面的结点里面加入下面的代码:
NBear连接字符串


这样就配置好了 NBear 的数据连接,他是连接到本地的 sqlserver 2005 express的。下面在结点下面输入下面的代码完成对 Roles providers 和 Membership providers 的配置:
Roles providers 和 Membership providers 的配置







 






其实很简单,就是把以前的那些 providers 的connectionStringName给设置成 NBear 数据连接的名字就ok了。还有一点我想说的因为是基于 Form 的安全机制,我们最好在开发整个系统之前就把整个系统规划以下,把所有同权限访问的文件放到同一个目录,这样便于使用 web.config 来配置权限。比如我们的所有后台管理的功能放到Admin这个文件夹,然后在文件夹下面建立一个web.config,然后配置他的内容为:
Admin目录下的web.config配置








这样就只允许在 admin 这个 roles 里面的用户访问。然后再在 admin 目录下面建立一个 super 文件夹,只允许具有super权限的用户访问,里面放置一些添加删除用户之类的页面。
基于 Div+CSS 的网页布局
以前长期的做 asp 的网站,养成的老毛病,什么东西都用table td 之类的搞定了,弄得整个页面很混乱,并且和业务逻辑绑在一起。最近参考了 NBear 的startkit 和一些其他的网站,发现他们都是用 div+css 来搞的网站布局排版和样式。慢慢研究看明白了之后才知道了网站换肤是怎么实现的,原来换个 Css 文件就一切搞定。
在 asp.net 2.0 开发的时候强调一切都做成控件,然后只需要在页面上把控件拖上去组装成你想要的页面。我自己在开发的时候就把基本上所有的功能都封装成了控件,根据需求拖拽ok。我把头上的酒店搜索封装成控件,管理菜单封装成控件,n多封装的控件。我把这些控件放到以功能命名的 div 上面,这样组装起来的页面也可以用css来控制。开发的时候我列了一个表格,下面给出来,可以参考以下(列表主要是为了方便以后写css文件的时候查阅):

基于MVP的架构
我在开发的时候发现用三层架构做这种小型的应用确实有点大材小用而且浪费资源。不过我这个人向来“执着”,索性把它搞得更复杂些。把以前的那种三层架构升级到基于 MVP 架构的体系结构。升级过程参考了 Teddy 的文章:
http://www.cnblogs.com/teddyma/archive/2006/12/20/598546.html
我换成 MVP 架构的主要原因是我在自己写 DataObject 的时候放到了web的App_Code目录,然后把那个DataObject绑定到一个ObjectDataSource上面,发现这样系统耦合了,开始的IoC做的都是在浪费工,参考了Teddy的文章之后决定升级到MVP架构,让以前的IoC作为model来用。后来发现把DataObject写到业务逻辑的实现里面也不犯错,一样的IoC。其实后来明白了Teddy的mvp也只不过是让页面不再依赖于ServiceInterface,而是让他依赖于一个ViewInterface和IPresenterInterface,然后把实现放到PresenterImpls里面,把IPresenterInterface和PresenterImpls当成IoC配置使用,很巧妙。
总结
这篇文章写的很混乱,感觉有用的东西不多,不过都是自己在做项目的时候一些体会。刚才再看深入研究ObjectDataSource,我项目里面要用,所以下次体会的时候主要谢谢ObjectDataSource这个控件的使用和扩展。

TrueLove 项目感悟(一)功能分析、数据库设计

昨天和老婆在网上聊天,她看了我的博客,问我最近为什么不写技术文章了。我相信也是的,已经有2个星期没有写过技术类的文章。虽然最近忙着做 TrueLove 这个酒店查询的网站,但是在做 TrueLove 项目的时候一些经验、技巧、感悟和问题也应该记录下来,以便以后查阅和与他人分享。所以准备写 TrueLove 项目感悟的系列文章。
我是第一次用 Asp.net 2.0 做网站,所以很多地方都是摸索着来做。在项目感悟里面写的东西虽然都是自己应用的技术和方法,但是不保证他是最好的或者是正确的。很多自己的观点在里面,希望大家多指正以下。我下面先来帖以下这个项目要实现的功能,以便让大家对这个项目有所了解。
1.1、酒店要能显示名称,级别(星级),地点(细化到城市),简介(详细的介绍),图片,联系方式(电话,传真,邮箱,网址)
1.2、酒店的热率(用户查看的次数),根据热率排行(热率相等按照id大到小排列)
1.3、酒店的详细信息中的房间的分类(总统套房,标间…)价格
1.4、酒店的图片(详细的图片,多张)
1.5、首页显示最热酒店
1.6、首页显示最新酒店
1.7、首页显示网站的统计(酒店个数,三星四星五星等分别个数)
1.8、根据级别,名称,地点和价格查询
1.9、根据地点,级别等列表浏览
1.10、根据热度自动生成辅助搜索最优化(类似百度最热关键字)
以上是这个项目的功能要求。对这个项目我打算用下面的技术架构来实现:采用三层架构(DAL,BLL,Web),对于数据访问层,包括数据库的设计我准备用 NBear 来做,很喜欢他的简单高效,并且 Teddy 就是园子里的,得到个技术支持啥的也比较方便。BLL 那里用了以下 IoC ,当然还是用的 NBear 的 IoC 框架了,比较方便。Web 里面准备使用一部分的 Asp.net Ajax 来增加一些用户体验。基本的实现打算就是这样,还有很多没有考虑到的地方,还是边做边改吧,毕竟等什么都准备好再开始就永远都开始不了了。
仿照 NBear 的 Starter Kit 先把大架搭建起来,下面是整个项目的命名和说明:
2.1、命名空间TrueLove
2.2、数据库设计:EntityDesigns
2.3、实体类:Entities
2.4、网站:website
2.5、IoC:ServiceInterfaces ServiceImpls
2.6、数据库命名:TrueLove(数据库表前缀缩写tl_(True Love))
命名规范定了以后,下面要开始设计数据库了。打开EntityDesigns工程,添加一个 NBear.Common.Design.dll 引用。然后开始根据 NBear 的规范设计数据库实体类。具体方法这里不嗷诉了,可以参考Teddy 的 ORM 设计的文章。下面给出我设计的数据库实体类图,大家看看这样设计是否合理:

还有要用到的列表的类图:

大家看看,这样是不是合理,有没有什么建议。谢谢啊。下面要配置 NBear 的 VS 插件了,以方便自动生成数据库,Entities 类和实体类配置文件。首先要安装 NBear 的 VS 插件,很简单,双击 SetupNBearVsPlugin.exe 就搞定了。这里主要的是写那个插件的配置文件。在 EntityDesigns 工程下面建立一个 EntityDesignToEntityConfig.xml 的文件,然后在里面输入下面的内容:
ReleaseTrueLove.EntityDesigns.dllTrueLove.Entities..\TrueLove.Entities\DbEntities.cs..\Website\Configs\EntityImpls.xmlC:\Program Files\Microsoft SQL Server\90\Tools\Binn.\sqlexpresssapwdTrueLove
虽然大部分的配置字节从字面意思上都可以明白,但是这里有几点需要注意和说明的:
1.Release 咱们默认的类库便宜模式为 Debug ,也就是说生成的类库 DLL 是在 bin\Debug 目录下面,而这里这配置成 Release 的话就找不到。我在这里就犯了一个莫名的错误,当心细心的朋友不用提醒也会修改的。
2. 这个关系到是否同步到数据库,只有设置成 True 他才可以自动同步到数据库。
3.C:\Program Files\Microsoft SQL Server\90\Tools\Binn 这个里面的路径问题,如果使用的是sql server 2005 或者 express 则这里的90地方不用修改,若是使用 sql server 2000 的话要把90修改成80.
以上的这些说明和注意都是弱弱的,不过我在做的时候他确实让我头疼的一会,厚着脸皮写出来,让和我一样粗心的朋友可以避免遭受我一样的郁闷。
配置好了 VS 的插件了,现在要做同步了,建立你 路径给出的文件,然后编译 EntityDesigns 工程,数据库、实体类、实体类配置文件一切都搞定了,也就可以说整个数据访问层已经搞定了。NBear 就是这么高效,很有前途的框架啊。
凌晨 1:30 了,有点累了。明天接着写吧。明天主要讲讲用基于 Form 的安全机制来搭建用户模块。
很高兴,今天进入了博客园的前500名。听首歌,给老婆打磨戒指去...

《Div+CSS布局大全》发布加下载

最近一段时间因为做 TrueLove 这个项目中使用了 div + css 的布局模式,需要学习了很多的div+css的布局的知识,所以浏览了大部分的文章,整理了以下,打包成册,做成了pdf格式的。office2007的发布提供的pdf生成功能弄得我总是很喜欢把大部分自己学习的资料整理成pdf文档。估计以后还会有大部分的这种文档提供。大家看看,我感觉内容基础的应该ok了。更高阶的自己去css-discuss网站看看,那里很牛的...
下载地址: http://www.cnblogs.com/Files/jessezhao/DIV+CSS布局大全.rar
PS:可能大部分的读者没有看到我的这句话“所以浏览了大部分的文章,整理了以下,打包成册,做成了pdf格式的”,也就是说文章都不是我所做的,是我整理的。没有排版是因为我整理只是为了方便查阅,保留其原有格式,作出个目录就能满足需求。还有接受了Cat Chen 的建议,本书和本博客在 Creative Commons 协议之下发布,具体协议内容请参看http://creativecommons.org/licenses/by-nc-sa/2.5/deed.zh