二十四画生的Blog


        ——开始学习MVC框架
posts - 90, comments - 1221, trackbacks - 46, articles - 8
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

  首先要说明一个概念,标题中所说的CBO是指的Custom Business Object Helper,也就是实现从数据库中读取数据并实例化自定义业务对象(Custom Business Object)的类。自定义业务对象(也可简称CBO)是保存数据的一种方法,用这种方法能让我们更方便的在业务逻辑层和表示层采用面向对象的方法来处理数据。在我以前的编程过程中也经常用到自定义业务对象。对实例化自定义业务对象的操作一般是:1、从数据库读取数据,以DataSet或DataTable取得数据。2、利用自定义业务对象的构造函数实例化每一个对象。3、然后再将实例化后的对象传第到业务逻辑层。这种方式是很麻烦的,不仅要写大量的代码来实现这种功能,而且难以维护,如果当一个自定义业务对象要增加一个属性的时候需要改动多处代码。
  在DNN中,大量的采用了自定义业务对象来保存数据。如果是使用我的方法,那实现起来可就复杂了。DNN中用了一个通用CBO类就实现了这个功能,而且还可以返回对象集合。要利用CBO类,自定义业务对象就必须看作关系数据库表结构的映射,类中定义的属性在查询返回的DataReader中都有一个相应的字段(同名且类型相同)。

一个简单的自定义业务对象(省略了一些代码):

Public Class HtmlTextInfo
   
' local property declarations
   Private _ModuleId As Integer
   
Private _DeskTopHTML As String

   
' initialization
   Public Sub New()
   
End Sub


   
' public properties
    Public Property ModuleId() As Integer
        
Get
            
Return _ModuleId
        
End Get
        
Set(ByVal Value As Integer)
            _ModuleId 
= Value
        
End Set
    
End Property


    
Public Property DeskTopHTML() As String
        
Get
            
Return _DeskTopHTML
        
End Get
        
Set(ByVal Value As String)
            _DeskTopHTML 
= Value
        
End Set
    
End Property


End Class


要从数据库中读取数据并实例化对象只需:(这段代码在HtmlTextController中)
Public Function GetHtmlText(ByVal moduleId As IntegerAs HtmlTextInfo
    
Return CType(CBO.FillObject(DataProvider.Instance().GetHtmlText(moduleId), GetType(HtmlTextInfo)), HtmlTextInfo)
End Function

如果HtmlTextInfo中的属性要改变也不需要改变这段代码。值得一提的是:DNN中大量采用了如**info和**Controller命名的类,它们分别提供属性和方法。我觉得这个方法很好,把属性方法都写在一个类中看起来的确不爽。

  CBO.FillObject是Custom Business Object Helper中的一个方法,完成从DataReader中提取数据并实例化对象的功能。CBO类的原理是利用.net中的反射机制,动态的从DataReader中读取数据,并给相应的对象属性赋值,从而起到实例化对象的效果。为了起到通用作用CBO.FillObject返回的对象都是object类型的,所以需要用CType进行转换。

CBO中的方法列表:
GetPropertyInfo:获取指定类型的全部属性信息,用ArrayList返回数据
GetOrdinals:返回命名字段的全部索引
CreateObject:创建指定类型实例
FillObject:通过IDataReader读取数据并实例化单一的对象
FillCollection:通过IDataReader读取数据并实例化对象集合到ArrayList中
InitializeObject:初始化对象实例
Serialize:将对象序列化成XML(好像没有什么地方用)
CloneObject:克隆对象(好像没有什么地方用)

以下是在DNN技术文档中找到的一些关于CBO的介绍:
DotNetNuke Data Access.doc
Custom Business Object Helper ( CBO )
In an effort to minimize the mundane coding task of populating custom business objects with information from the data layer ( passed as DataReader ), a generic utility class has been created for this purpose. The class contains two public functions - one for hydrating a single object instance and one for hydrating a collection of objects ( ArrayList ). The routine assumes that each property in the class definition has a corresponding field in the DataReader. The atomic mapping of information must be identical in terms of Name and Data Type. The code uses Reflection to fill the custom business object with data and close the DataReader

DotNetNuke Membership.doc
CBO- the DotNetNuke business layer can be used to call multiple data stores and aggregate the data into custom business objects. The technique is the most extensible; however, it also introduces a performance impact. Overall it is still the preferred option.

DotNetNuke Module Developers Guide.doc
If you are returning data to the SurveyOptionInfo object for later binding in a control within your user interface, the Custom Business Object (CBO) helper class provides the hydration of the object. The CBO is part of the DNN core framework and provides the hydration of the objects when there is a return from a database call, as in this case a call to a stored procedure.
这篇文章中也提到了CBO:
http://www.cnblogs.com/ericguo/archive/2005/02/06/102927.html

 

Feedback

#1楼   回复  引用    

2005-06-20 16:54 by question
Public Shared Function FillObject(ByVal dr As IDataReader, ByVal objType As Type, ByVal ManageDataReader As Boolean) As Object

Dim objFillObject As Object
Dim intProperty As Integer

' get properties for type
Dim objProperties As ArrayList = GetPropertyInfo(objType)

' get ordinal positions in datareader
Dim arrOrdinals As Integer() = GetOrdinals(objProperties, dr)

Dim Continue As Boolean
If ManageDataReader Then
Continue = False
' read datareader
If dr.Read() Then
Continue = True
End If
Else
Continue = True
End If

If Continue Then
' create custom business object
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals)
Else
objFillObject = Nothing
End If

If ManageDataReader Then
' close datareader
If Not dr Is Nothing Then
dr.Close()
End If
End If

Return objFillObject

End Function

在这段代码中,ManageDataReader的作用是什么,愿有给解释一下

#2楼[楼主]   回复  引用  查看    

2005-06-20 17:40 by 二十四画生      
ManageDataReader应该是是否改变DataReader位置的标记,如果为False表示不改变DataReader位置也不关闭DataReader。
ManageDataReader为False的情况程序中没有出现,可能是用于:在另一个类方法中已经用dr.Read()读取了一行数据,用FillObject实例化对象后还需要对DataReader中的数据进行其它操作,所以也不能关闭DataReader。

#3楼   回复  引用    

2005-06-20 20:50 by 春鱼
CBO 虽然简化了从关系数据库到业务实体的数据读取过程, 但并没有在二者之间提供抽象. 也就是说, 这里说的"业务实体"是假的业务实体. 或者说是和"关系"紧密联系的业务实体. 实际上这样的业务实体只是关系的另外一种表现形式. 我们无非是完全照着数据库的字段明明重写了一次public property 而已. 除此之外, CBO什么都不是. 徒然增加书写代码的工作量而已.

#4楼[楼主]   回复  引用  查看    

2005-06-20 22:00 by 二十四画生      
@春鱼
CBO就是完成“关系/对象”的转换过程。在这一过程上的确是简化了代码。Custom Business Object就是关系数据的映射,你说它是“假的业务实体”,那么“真的业务实体”是怎样的呢?希望能够说明,谢谢!

#5楼   回复  引用  查看    

2005-06-21 11:21 by OK,Let'S Enjoy Our New Life!      
CBO的“关系/对象”转换过程抽象出来,好处是代码写少了,只需要一个公共的转换过程,当然它使用反射,在性能上可能有些损失;而与关系表紧密相连的*Info则可以通过代码生成工具生成,因为这些属性读写器有一样的面孔。
@春鱼 & 楼主:“CBO是指的Custom Business Object Helper”,而非Custom Business Object.太多的期望好像会使CBO更复杂。

#6楼   回复  引用    

2005-06-24 18:17 by kevinlin
TO: OK,Let'S Enjoy Our New Life!
Dnn使用了缓存将反射的信息保存起来,这样就可以提高性能了.

#7楼   回复  引用  查看    

2007-04-19 22:02 by ToBin      
非常有用,现在正为这个发愁呢
我的DNN模块是c#的,本人E文只有4级水平,上网还不方便,很多地方不是很明白.勉强能开发个简单的模块.现在没办法才来深究.大哥的博客很很有用的!!、
public JobsInfo GetJobs(int ModuleId, int ItemId)
{
//
return CBO.FillObject < JobsInfo >(DataProvider.Instance().GetJobs(ModuleId, ItemId));

}

/// -----------------------------------------------------------------------------
/// <summary>
/// gets an object from the database
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="moduleId">The Id of the module</param>
/// <history>
/// </history>
/// -----------------------------------------------------------------------------
public List<JobsInfo> GetJobss(int ModuleId)
{
return CBO.FillCollection< JobsInfo >(DataProvider.Instance().GetJobss(ModuleId));
}



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 177542




相关文章:

相关链接: