跟大家一起学习,一起进步 2005 坚强 努力 整洁

导航

DotNetNuke (DNN) 2.x Module Architecture, Part II

In this second part of a three part series we will cover the Business Logic Layer, and the Data Abstraction Layer of module Architecture of DotNetNuke.

If you're not familiar with DotNetNuke, be sure you visit http://www.dotnetnuke.com to learn more about this fast growing open source portal that you can use and develop against absolutely free.

In the previous article we discussed how to get your module project set up, we also began development on the user interface pieces of our module. In this article we're going into what makes the DNN architecture stand out from most .NET applications available, specifically the data provider model. The provider model is a dominant theme in the upcoming Visual Studio 2005 release, and is what makes DNN flexible enough to have any database as the backend. Here we will cover the Business Logic Layer, and Data Abstraction Layer of the DNN architecture, in part III of this series we will finish it up with an overview of the Database Provider class.

BLL, and DAL

I'm sure the previous acronyms are ones you've seen tossed around if you're an avid user of the ASP.NET forums. What do these stand for?

  • Business Logic Layer (BLL) - Contains all the logic that is specific to your business. For example, if you debit one account and then credit another account, this would occur in the BLL.
  • Data Abstraction Layer - This is the layer within your application that connects to the data provider. It contains overridable methods that your provider will over ride for it's specific vendor database. Your application's BLL will interface with the DAL via a custom business objects helper class (CBO).

The custom business object helper class is basically a class that populates a collection of objects or objects that you created within your module. Usually these objects are directly related to stored procedures or queries from your database.

Reflection versus Abstraction

There are definitely plenty of changes here in DNN 2.x, in DNN 1.x we obtained data from our database using reflection. The major problem with the previous architecture of DNN was the lack of a clear definition between our different layers, i.e. data tier, business logic, and user tiers. Now with the provider model we have a clear separation of these tiers.

Another big improvement in DNN 2.x architecture is performance. Thanks to abstraction and caching techniques there has been a huge performance increase as exhibited in the following metrics:

DotNetNuke 2.0 ( DAL enhancement )
Total number of requests: 				    	93,254 
Total number of connections: 				    	93,253 
  
Average requests per second: 				      	310.85 
Average time to first byte (msecs): 				2.37 
Average time to last byte (msecs): 				2.46 
Average time to last byte per iteration (msecs): 			29.58 
  
Number of unique requests made in test: 				12 
Number of unique response codes: 				1 

DotNetNuke 1.0.10 ( SqlCommandGenerator )
Total number of requests:					42,350
Total number of connections:					42,350
		
Average requests per second:					141.17
Average time to first byte (msecs):				6.02
Average time to last byte (msecs):				6.15
Average time to last byte per iteration (msecs):			116.94
		
Number of unique requests made in test:				17
Number of unique response codes:				2

As you can see response time has been improved phenomenally!

Business Logic Layer

Now let's get into the different classes you will need to create for interacting with a database. In part I of this series we examined the user interface pieces of the survey module that comes bundled with the DNN distribution, now lets look at the BLL piece. In the survey example the BLL class is the SurveyDB.vb, in your modules you would follow the same naming convention, i.e.: ModuleNameDB. Within this file is at least two classes for your module, a ModuleInfo class and a ModuleController, for this example SurveyInfo, and SurveyController. Here's a description of these two classes:

  • ModuleInfo: Sets and gets public properties for our objects being generated by our controller class.
  • ModuleController: Used for obtaining objects,, basically uses the custom business objects helper class to populate data from our data provider into a collection of objects.

Let's look at the SurveyInfo class and see what's going on in there:

Imports System
Imports System.Data
Imports DotNetNuke

Namespace YourCompanyName.Survey
    Public Class SurveyInfo
        ' local property declarations
        Private _SurveyId As Integer
        ::
        ' initialization
        Public Sub New()
        End Sub
        ' public properties
        Public Property SurveyId() As Integer
            Get
                Return _SurveyId
            End Get
            Set(ByVal Value As Integer)
                _SurveyId = Value
            End Set
        End Property
        ::
 End Class
        

Basically a simple class that is exposing prosperities for our controller class. Now let's look at the controller class:

Public Class SurveyController
  Public Function GetSurveys(ByVal ModuleId As Integer) As ArrayList
    Return CBO.FillCollection(DataProvider.Instance().GetSurveys(ModuleId), _
      GetType(SurveyInfo))
  End Function

  Public Function GetSurvey(ByVal SurveyID As Integer, _
      ByVal ModuleId As Integer) As SurveyInfo
    Return CType(CBO.FillObject(DataProvider.Instance().GetSurvey(SurveyID, ModuleId), _
      GetType(SurveyInfo)), SurveyInfo)
  End Function

  Public Sub DeleteSurvey(ByVal SurveyID As Integer)
    DataProvider.Instance().DeleteSurvey(SurveyID)
  End Sub

  Public Function AddSurvey(ByVal objSurvey As SurveyInfo) As Integer
    Return CType(DataProvider.Instance().AddSurvey(objSurvey.ModuleId, objSurvey.Question, _
      objSurvey.ViewOrder, objSurvey.OptionType, objSurvey.CreatedByUser), Integer)
  End Function

  Public Sub UpdateSurvey(ByVal objSurvey As SurveyInfo)
    DataProvider.Instance().UpdateSurvey(objSurvey.SurveyId, objSurvey.Question, _
      objSurvey.ViewOrder, objSurvey.OptionType, objSurvey.CreatedByUser)
  End Sub
End Class

.So what's going on the controller class? If you look at the code above you will see several methods, GetSurveys, GetSurvey, DeleteSurvey, AddSurvey, and UpdateSurvey. In most cases these routines directly correspond to a stored procedure contained within your database. For example, there is a GetSurveys stored procedure in our database that accepts ModuleID as a parameter, and returns a record. Now in the controller class you are doing something similar here, in the GetSurveys method you accept the ModuleID as input (which will be passed to the provider class for database execution). Then the return will be of type SurveyInfo. Remember in SurveyInfo we defined properties for our class, these properties normally correspond to fields contained within our database. We now create an collection object for our module to work with instead of a record set or data reader. This combined with the data provider classes is what provides abstraction from our vendor's database.

Looking more into this class you see that the GetSurveys method first calls a CBO method, which is passed an instance of our data abstraction class. The CBO or custom business object class is what takes the data from our database via the data abstraction class, and then populates a collection of objects as the return to our BLL. So the main concept here is we don't directly work with data from database calls, our module deals with a collection of objects that contain properties that we defined in our SurveyInfo class.

Another thing to note is when you are doing update, add, and delete operations there is no need to wrap your call within the CBO method, because in most cases there is no return coming from the database.

posted on 2004-12-11 17:08  icfarmer  阅读(594)  评论(0)    收藏  举报