views:

333

answers:

3

I'm currently about two-and-a-half weeks in to my first ASP.Net MVC application, and so far, I love it.

This current project is a port of an ASP.Net WebForms project, and I am trying to maintain functionalty. All is going well.

However, I find myself repeating... myself.

For example, In my BaseController class, in my BaseViewPage, in my BaseViewUserControl, AND in my BaseViewMasterPage, I have the following code:

protected LanLordzApplicationManager AppManager
{
    get
    {
        if(Session["Application"] == null)
        {
            Session["Application"] = new LanLordzApplicationManager(Server.MapPath("~/"));
        }

        return (LanLordzApplicationManager)Session["Application"];
    }
}

protected User CurrentUser
{
    get
    {
        if (Session["UserID"] == null && this.Request.Cookies["AutoLogOnKey"] != null && !string.IsNullOrEmpty(this.Request.Cookies["AutoLogOnKey"].Value))
        {
            this.CurrentUser = this.AppManager.RecallUser(this.Request.Cookies["AutoLogOnKey"].Value, Request.UserHostAddress);
        }

        if (Session["UserID"] == null)
        {
            return null;
        }
        else
        {
            return this.AppManager.GetUserByUserID((long)Session["UserID"]);
        }
    }
    set
    {
        Session["UserID"] = value.UserID;
    }
}

Now, this is not beautiful code. I would like to fix it up a little bit, but as of right now, I'm fixing it in four places. It has been, in fact, the source of a couple of bugs, which meant fixing it in all four places again.

How would you suggest I keep this system DRY? Note that both of these objects must be kept on the session for more than a couple of reasons.

+3  A: 

In App_Code, create a class "BaseUtils" or somesuch, containing that functionality; then you simply have to include reference it where needed...

public class BaseUtils 
{
     public static LanLordzApplicationManager getAppMgr()
     {
         HttpSession Session = HttpContext.Current.Session;
         if(Session["Application"] == null)
         {
            Session["Application"] = new LanLordzApplicationManager(Server.MapPath("~/"));
         }

         return (LanLordzApplicationManager)Session["Application"];

     }


}

and in your page,

protected LanLordzApplicationManager AppManager
{
    get
    {
        return BaseUtils.getAppMgr();
    }
}

And similarly for the other two methods...

Stobor
+3  A: 

You could remove the code from BaseViewPage, BaseViewUserControl and BaseViewMasterPage. All data used in rendering the views can be passed to them from the controller as viewdata which is already available in all the views. This centralizes your code at least to the controller base class.

Blake Taylor
Some of the view logic is based on the CurrentUser object. In most cases, I don't want to pass that along from the controller. That is, I want the User to be universally accessible.
John Gietzen
+3  A: 

Use Mixins!

interface IWebRequestable { 
     HttpWebRequest Request {get;}   // Right class? Not sure.
}

public class BaseUserControl : UserControl, IWebRequestable {}
public class BaseController : Controller, IWebRequestable {}
public class BasePage : Page, IWebRequestable {}

public static class CurrentUserMixin {
    public static User GetCurrentUser(this IWebRequestable RequestObject) {
         // Put your User code here
    }
}
Paul Betts