Lets go further with maintainability. I'll quote my other answer about using Session:
Lets say we want to store shopping cart is Session of our ASP.NET MVC application. It will be stored in Session["ShoppingCart"]
, but we want easy, strongly typed access and high testability:
First we define interface:
public interface ISessionWrapper
{
List<CartItem> ShoppingCart { get; set; }
}
Then we make HttpContext implementation:
public class HttpContextSessionWrapper : ISessionWrapper
{
private T GetFromSession<T>(string key)
{
return (T) HttpContext.Current.Session[key];
}
private void SetInSession(string key, object value)
{
HttpContext.Current.Session[key] = value;
}
public List<CartItem> ShoppingCart
{
get { return GetFromSession<List<CartItem>>("ShoppingCart"); }
set { SetInSession("ShoppingCart", value); }
}
}
GetFromSession and SetInSession are helper method that make taking and setting data in Session easier. They can be easily reused to access other fields in Session.
Then we define our base controller (applicable to ASP.NET MVC):
public class BaseController : Controller
{
public ISessionWrapper SessionWrapper { get; set; }
public BaseController()
{
SessionWrapper = new HttpContextSessionWrapper();
}
}
If you want to use Session outside controller, you just create or inject new HttpContextSessionWrapper().
You can replace SessionWrapper with ISessionWrapper mock in Controller tests, so it is not dependent on HttpContext anymore. Session is also more easy to use, because instead of calling (List<CartItem>)Session["ShoppingCart"]
, you call SessionWrapper.ShoppingCart
. It looks nicer, isn't it?
If you don't use model class for view and I think using model class is better, you can do the same with ViewData:
public interface IViewDataWrapper
{
List<CartItem> ShoppingCart { get; set; }
}
public class ViewDataWrapper : IViewDataWrapper
{
}
public class BaseController : Controller
{
public IViewDataWrapper ViewDataWrapper { get; set; }
public BaseController()
{
IViewDataWrapper = new ViewDataWrapper();
}
}
And then simply in controller:
ViewDataWrapper.ShoppingCart = SessionWrapper.ShoppingCart
or if you decide not to use ViewData and specific model:
Model.ShoppingCart = SessionWrapper.ShoppingCart
And simply in view (if you define base class for view and introduce this interface):
<%= ViewDataWrapper.ShoppingCart %>
or
<%= Model.ShoppingCart %>
No mistyped strings, strongly typed, nice looking.