CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

David Hayden [MVP C#]

         .NET Tutorials, Patterns, and Practices

GRASP Patterns - Controller - DotNetNuke and Community Server Source Code Examples

As I mentioned before, Applying UML and Patterns by Craig Larman has an extensive description of GRASP, General Responsibility Assignment Software Patterns, which is a learning aid for OO design with responsibilities.  There are 9 GRASP Patterns: Controller, Creator, High Cohesion, Indirection, Information Expert, Low Coupling, Polymorphism, Protected Variations, and Pure Fabrication.

I talked about the Information Expert GRASP Pattern as it relates to the Create a Shopping Cart example in the following 2 posts:

I briefly mentioned this next GRASP Pattern, Controller GRASP Pattern, when we walked through both the DotNetNuke and Community Server source code in the following 2 posts:

Let's talk about the Controller GRASP Pattern in more detail:

  • Pattern Name: Controller
  • Problem: What first object beyond the UI layer receives and coordinates ("controls") a system operation?
  • Solution:  Assign the responsibility to a class representing one of the following choices:
    • Represents the overall “system,“ a “root object,“ a device that the software is running within, or a major subsystem - there are all variations of a facade controller.
    • Represents a use case scenario within which the system event occurs, often named <UseCaseName>Handler, <UserCaseName>Coordinator, or <UseCaseName>Session (use case or session controller). Use the same controller class for all system events in the same use case scenario.

If you open up the CommunityServerBlogs project that is part of the Community Server source code, you will see four controller classes that are responsible for handling system operations for all UI controls that handle blog related activities:

 

CommunityServerBlogs Controller Classes
  • BlogFeedback - Handles system messages with regarding feedback for blog posts.
  • WeblogGroups - Handles system messages associated with groups of blogs.
  • WeblogPosts - Handles system messages associated with individual blog posts.
  • Weblogs - Handles system messages associated with individual blogs.

 

If we re-look at the walk-thru we did of the Community Server source code, we talked about how the EntryViewContainer usercontrol used the controller class, WeblogPosts, to obtain the main post and comments for a particular BlogID and PostID to be displayed to the reader.  Here is a snippet of the code showing the usercontrol and controller classes collaborating:

 

EntryViewContainer
public class EntryViewContainer :  WeblogThemedControl
{
    // ...

    void BindData()
    {
        CSContext csContext = CSContext.Current;

        BlogPostQuery query = new BlogPostQuery();
        query.PostID = csContext.PostID;

        string name = Context.Request.QueryString["PostName"];
        if(!Globals.IsNullorEmpty(name))
            query.Name = name;

        query.IncludeCategories = false;
        query.ReturnFullThread = true;
        query.BlogID = CurrentWeblog.SectionID;
        
        PostSet ps =  WeblogPosts.GetPosts(query,true);
 
    // ...
}

 

WeblogPosts Class
public class WeblogPosts
{
    private WeblogPosts(){}
    
    // ...

    public static PostSet GetPosts(BlogPostQuery query, bool cacheable)
    {
        string key = cacheable ? query.Key : null;
        PostSet ps = null;
        
        if(cacheable)
            ps = CSCache.Get(key) as PostSet;

        if(ps == null)
        {
            WeblogDataProvider wdp = WeblogDataProvider.Instance();
            ps = wdp.GetPosts(query);

            if(cacheable)
                CSCache.Insert(key,ps,30,System.Web.Caching.CacheItemPriority.Low);
        }

        return ps;
    }
    
    // ...
}

 

DotNetNuke uses a similar architecture and also spells out the controller class by ending its name with "Controller."  How nice is that :)  Below is a snippet of the code we discussed while digging into the DotNetNuke source code.  The code shows the HtmlModule usercontrol collaborating with the HtmlTextController to get the HTML for this particular module based on its ModuleId.

 

HtmlModule.ascx.vb
Private Sub Page_Load

    ' ...
    
    Dim objHTML As New HtmlTextController
    Dim objDr As HtmlTextInfo = objHTML.GetHtmlText(ModuleId)
    
    ' ...

End Sub

 

HtmlTextController.vb
Public Function GetHtmlText(ByVal moduleId As Integer) As HtmlTextInfo

    Return CType(CBO.FillObject(DataProvider.Instance().GetHtmlText(moduleId),
                    GetType(HtmlTextInfo)), HtmlTextInfo)

End Function

On a final note, the controller class sits in the domain layer, but isn't really supposed to do much.  It's job is just to hand off the request to another domain object that does the work.  As you can see in the above 2 examples, WeblogPosts just quickly checks the cache and returns the PostSet if it is there or passes the request to the WeblogDataProvider.  It is essentially just delegating the work. The same thing holds true for HtmlTextController.  It just hands off the request to the appropriate data provider.

It's awesome to be able to see these patterns in action in both Community Server and DotNetNuke.



Comments

Jeff Perrin said:

# April 14, 2005 8:26 PM

David Hayden said:

Jeff Perrin has some excellent comments regarding my previous post describing the GRASP Controller Pattern,...
# April 15, 2005 10:22 AM
Check out Devlicio.us!

Our Sponsors

This Blog

Syndication

News

CodeBetter.Com Home