New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

  • 4/7/2015




Last updated long time ago



(Enter the content of this article below)


The DotNetNuke has long exposed the Common Business Objects (DotNetNuke.Common.Utilities.CBO) class to make it easier for developers to persist and retrieve objects to and from the database. Prior to generics being introduced in ASP.Net 2.0, the following two methods for retrieving either a single object or an ArrayList of multiple objects were most often used to fill or hydrate an object from a passed in DataReader:

Public Shared Function FillObject(ByVal dr As IDataReader, ByVal objType As Type) As Object

Public Shared Function FillCollection(ByVal dr As IDataReader, ByVal objType As Type) As ArrayList

Their generic versions which should be used with ASP.Net 2.0 and above are:

Public Shared Function FillObject(Of TObject)(ByVal dr As IDataReader) As TObject

Public Shared Function FillCollection(Of TItem)(ByVal dr As IDataReader) As List(Of TItem)

Although those methods make the developer's work easier and less prone to error by properly managing and closing the passed in DataReader when finished, they do their "magic" by making use of .Net reflection to discover the properties of the object class being filled and to map property name to corresponding database column name. Reflection is a costly operation performance wise and is best avoided in production code especially if the database is hit each time an object or collections of objects are retrieved.

In DotNetNuke 4.06.00, the IHydratable interface (DotNetNuke.Entities.Modules.IHydratable) was introduced. It defines only two member signatures which must be implemented in your custom object's entity class:

Namespace DotNetNuke.Entities.Modules

Public Interface IHydratable
Property KeyID() As Integer

Sub Fill(ByVal dr As IDataReader)
End Interface
End Namespace

The KeyID property which is used by the CBO class when filling a dictionary is most easily implemented as a wrapper around your entity class' already existing key or identity property. It is not necessary to add a new column named "KeyID" to the object's table in the database. For example, if your class had defined the column "ItemID" in the database and it uniquely identifies each row in the table corresponding to your entity class, the KeyID property may be implemented as follows:

Public Property KeyID() As Integer Implements DotNetNuke.Entities.Modules.IHydratable.KeyID

Return ItemID
End Get
Set (ByVal value As Integer)
ItemID = value
End Set
End Property

The implementation of the Fill method simply retrieves each of your entity class' properties from the passed-in DataReader. For example, in a simple entity class which exposes only the three properties - ItemID, ModuleID, and ItemContent, the implementation of the Fill method would be as follows:

Public Sub Fill (ByVal dr As IDataReader) Implements DotNetNuke.Entities.Modules.IHydratable.Fill

ItemID = Null.SetNullInteger (dr("ItemID"))
ModuleID = Null.SetNullInteger (dr("ModuleID"))
ItemContent = Null.SetNullString(dr("ItemContent"))
DateCreated = Null.SetNullDateTime(dr("DateCreated"))
End Sub

In the above code, the Null class is a utility class (DotNetNuke.Common.Utilities.Null) containing shared methods which help convert between database null objects and the default application null values of common system types. For example, if the database row passed in the DataReader contains a database null for column of type int, Null.SetNullInteger will return -1.

When called upon to fill an object whose class has implemented IHydratable, the various CBO Fillxxxxxxx methods will no longer have to resort to less-performant reflection techniques but will call the object's Fill method implementation instead.

Another advantage of implementing IHydratable is that your entity class may (but does not have to) expose some or all of its properties as ReadOnly properties. The implementation of Fill can simply assign the value of a column retrieved from the DataReader directly to the class property's internal data store. For example:

Private _CreatedDate As DateTime

Public ReadOnly Property CreatedData As DateTime
Return _CreatedDate
End Get
End Property

Public Sub Fill (ByVal dr As IDataReader) Implements DotNetNuke.Entities.Modules.IHydratable.Fill
' . . . Other assignments as in prior example
_CreatedDate = Null.SetNullDateTime(dr("CreatedDate"))
End Sub

The only downside of implementing IHydratable in your entity classes is that should you later add new columns to the corresponding database table and modify your stored procedures to return those values, you must also remember to revise your implementation of IHydratable's Fill method accordingly.

In DotNetNuke 5.00.00, a new base class, DotNetNuke.Entities.BaseEntityInfo, was introduced to include the following standard readonly audit properties: CreatedByUserID, CreatedOnDate, LastModifiedByUserID, and LastModifiedOnDate which correspond to columns of the same name added to the table used to store your enty class objects which inherit from BaseEntityInfo. BaseEntityInfo exposes the following method:

Protected Overridable Sub FillInternal(ByVal dr As System.Data.IDataReader)

When implementing IHydratable.Fill in your custom entity class, don't forget to first call BaseEntityInfo.FillInternal as well to hydrate it's properties:

Public Sub Fill (ByVal dr As IDataReader) Implements DotNetNuke.Entities.Modules.IHydratable.Fill

' . . . Other assignments as in prior example
End Sub

In DotNetNuke 5.04.00, another new base class, DotNetNuke.Entities.Content.ContentItem, from which your entity classes may inherit was introduced. The ContentItem class which itself inherits from BaseEntityInfo paves the way for easily adding support for taxonomy, tagging and other ContentItem dependant features (perhaps in future versions comments, reviews, ratings, etc.) to your DotNetNuke extensions. Because ContentItem already implements IHydratable, you will not do so in your custom entity class. Instead, you will need to create overrides of the KeyID property and the Fill method already implemented in the ContentItem class. Don't forget to call ContentItem's FillInternal method in your Fill method override:

Public Overrides Sub Fill(ByVal dr As System.Data.IDataReader)

'. . . Assignments to other properties as above
End Sub


A Sneak Peek 3 IHydratable Part 1

A Sneak Peek 4 - IHydratable Part 2

IHydratable-Use the CBO Again For Your DotNetNuke Module

IHydratable-An Interesting Side Effect

No sections defined
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out