Dec 6, 2011

Types - Back to Basic

Value Type
• Non-object types
• Stored in memory “stack”
• int, long, char, byte,float, double,decimal,bool etc.
• Structs,Enumerations

Reference Types
• Object types
• Stored in memory “heap”
• Variables are “pointers” to memory location

Memory Allocation
The Common Language Runtime allocates memory for objects in two places: the stack and the heap. The stack is a simple first-in last-out memory structure, and is highly efficient. When a method is invoked, the CLR bookmarks the top of the stack. The method then pushes data onto the stack as it executes. When the method completes, the CLR just resets the stack to its previous bookmark—“popping” all the method’s memory allocations is one simple operation!
In contrast, the heap can be pictured as a random jumble of objects. Its advantage is that it allows objects to be allocated or deallocated in a random order. As we’ll see later, the heap requires the overhead of a memory manager and garbage collector to keep things in order.

void CreateEmployee()
{
Employee myEmployee = new Employee();     // Employee is a class
Employee myEmployee1;
myEmployee1 = myEmployee;

//Since this is being passed as value type a copy of reference variable will be
//passed to DoSomeWork which will point to the same employee objct so
//any modification to the actual employee object will be visible here.
DoSomeWork(myEmployee);
}

void DoSomeWork(Employee employee)
{
employee.WorkCompleted = True; //Since this is modification to the actual object this will be visible in the calling function
employee = null; //Since this is modification to the local variable this will not impact anything in the calling function.
}

In this method, we create a local variable myEmployee that references an Employee object. The local variable is stored on the stack, while the Employee itself is stored on the heap. Also in the third line we are saying that local variable myEmployee1 reference to the same Employee object, so modification to the Employee object will be reflected from the both references myEmployee as well as myEmployee1

Stack                                  | Heap
                                          |
myEmployee Reference----   |----->Employee object
                                          |
                                          |

The stack is always used to store the following two things:
• The reference portion of reference-typed local variables and parameters
• Value-typed local variables and method parameters (structs, as well as integers, bools, chars, DateTimes, etc.)

The following data is stored on the heap:
• The content of reference-type objects.

Memory Disposal
Once CreateEmployee has finished running, its local stack-allocated variable, myEmployee, will disappear from scope and be “popped” off the stack. However, what will happen to the now-orphaned object on the heap to which it was pointing? The answer is that we can ignore it—the Common Language Runtime’s garbage collector will catch up with it some time later and automatically deallocate it from the heap. The garbage collector will know to delete it, because the object has no valid referee.

The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used, however, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.

Dec 5, 2011

Parallel Programming

You can simply spin a new thread and assign some work

Thread t = new Thread(DoSomething);
 // Start the thread
 t.Start();
 // Request that oThread be stopped
 t.Abort();
 // Wait until oThread finishes. Join also has overloads
 // that take a millisecond interval or a TimeSpan object.
 t.Join();
 //This will throw ThreadStateException since aborted threads cannot be restarted
 oThread.Start();
 
The above approch is good for jobs which are going to be relatively long running

Issues
1. Spinning up a new thread and tearing one down are relatively costly actions, especially if compared to the cost of a small work being performed in the thread
2. Oversubscription is another issue. If too many threads are running, we’d have two components each fighting for the machine’s resources, forcing the operating system to spend more time context switching between components. Context switching is expensive for a variety of reasons, including the need to persist details of a thread’s execution prior to the operating system context switching out the thread and replacing it with another.

ThreadPool
.NET Framework maintains a pool of threads that service work items provided to it. The main method for doing this is the static QueueUserWorkItem

using (ManualResetEvent mre = new ManualResetEvent(false))
 {
  ThreadPool.QueueUserWorkItem(delegate{DoSomething();});
  ThreadPool.QueueUserWorkItem(delegate{DoSomethingelse();});
  ThreadPool.QueueUserWorkItem(delegate{DoSomeMore();});
  // Wait for all threads to complete.
  mre.WaitOne(1000000);
 }
 
1. So no overhead of thread creation and tear down.
2. Minimizes the possibility of oversubscription.
3. Once your machine is sufficiently busy, the threadpool will queue up requests rather than immediately spawn more threads.

Issues
1. There is a lim­ited num­ber of threads in the .Net Thread Pool (250 per CPU by default), and they are being used by many of the .Net frame­work classes (e.g. timer events are fired on thread pool threads) so you wouldn’t want your appli­ca­tion to hog the thread pool.
2. You cannot set the priority.

.Net 4.0
Parallel programming become much easier with the release of  .Net 4.0 System.Threading.Tasks.Parallel

ParallelLoopResult loopResult =
 Parallel.For(0, 100, (y,loopState) => 
 { 
  Console.WriteLine("This is " + y);
  //The other option is Break which gurantees that all the iterations till the breaking iterations are completed
  if(y > 20) loopState.Stop();
  if(loopState.IsStopped)
   Console.WriteLine("Loop was stopped while I am processing this");
 });
 Console.WriteLine("Ran to completion: " + loopResult.IsCompleted);


CancellationTokenSource cts = new CancellationTokenSource();
 var options = new ParallelOptions { CancellationToken = cts.Token };

 Task.Factory.StartNew(() =>
 {
  Thread.Sleep(3000);
  cts.Cancel();
 });

 try
 {
  Parallel.For(0, 10000, options, (y, loopState) =>
  {
   Thread.Sleep(1000);
   options.CancellationToken.ThrowIfCancellationRequested();
   Console.WriteLine("This is " + y);
  });
 }
 catch (OperationCanceledException e)
 {
  Console.WriteLine(e.Message);
 }


VERY SMALL LOOP BODIES

As previously mentioned, the Parallel class is implemented in a manner so as to provide for quality load balancing while incurring as little overhead as possible. There is still overhead, though. The overhead incurred by Parallel.For is largely centered around two costs:
1) Delegate invocations - Invoking a delegate incurs approximately the same amount of cost as a virtual method call.
2) Synchronization between threads for load balancing.

Task task1 = Task.Factory.StartNew(() => DoSomething(par1));
 Task task2 = Task.Factory.StartNew(() => DoSomething(par2));

 Task[] tasks = new Task[] {task1, task2};
 Task.WaitAll(tasks);

 Parallel.Invoke(
 () =>  DoSomething("1"),()=>DoSomething("1"));


Reference
http://www.microsoft.com/download/en/details.aspx?id=19222

Singleton - Highlander Pattern "There can be only one!"

There can be only one
There are some object we want to share system wide
• Expensive to Create
• Represent a single instance entity
• Shared State
• Database connection

Example
• Cache
• Logging
• Database connection

1st Solution

public static class Cache
 {
  private static Cache cache = new Cache();

  private Cache() {}

  public static Cache Current
  {
   get { return cache; }
  }
  
  public static void AddToCache(Object o, Object key)
  {
   //Write logic to add to cache
  }
  
  public static object GetFromCache(Object key)
  {
   //Write logic to add to cache
  }
 }

 Cache.Current.AddToCache(o,key)
 Cache.Current.GetFromCache(key)

So by making constructor private, we insure that the class cannot be instantiated in any other way except by accessing the Current property.

Issue with the above solution
• Since static types lack some of the more useful oo features like polymorphism

Next Approach

public class Cache
 {
  private static Cache cache = new Cache();

  private Cache() { }

  public static Cache Current
  {
   get { return cache; }
  }
  
  public static void AddToCache(Object o, Object key)
  {
   //Write logic to add to cache
  }
  
  public static object GetFromCache(Object key)
  {
   //Write logic to add to cache
  }
 }

 Cache.Current.AddToCache(o,key)
 Cache.Current.GetFromCache(key)

Here the class is not marked as Static and also there is only one way to obtain an instance outside the class.

Issue
When does the instance of Cache gets created?
If a class does not have a static constructor then it is marked 'BeforeFieldInit'. In this
circumstance, according to the ECMA spec "If marked BeforeFieldInit then the type's
initializer method is executed at, or sometime before, first access to any static field
defined for that type", this is a loose guarantee. It means that there is no guarantee when
the initializer is run, it could be when the type is loaded, when the first static method is
called or when the field itself is accessed.
If an exception fires during the construction of the object this exception is held and re-thrown on first use of the type

Lazy Initialization


public class Cache
 {
  private static Cache cache;

  static Cache() 
  {
   cache = new Cache();
  }

  public static Cache Current
  {
   get { return cache; }
  }
  
  public static void AddToCache(Object o, Object key)
  {
   //Write logic to add to cache
  }
  
  public static object GetFromCache(Object key)
  {
   //Write logic to add to cache
  }
 }

 Cache.Current.AddToCache(o,key)
 Cache.Current.GetFromCache(key)


By explicitly adding a static constructor this changes the behavior of the CLR to perform lazy initialization, so the logger instance is not created until we actually need it.A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

Lazy Initialization By Hand


public class Cache
 {
  private static Cache cache = null;

  static Cache(){}

  public static Cache Current
  {
   if (cache == null)
    cache = new Cache();
   return cache; 
  }
  
  public static void AddToCache(Object o, Object key)
  {
   //Write logic to add to cache
  }
  
  public static object GetFromCache(Object key)
  {
   //Write logic to add to cache
  }
 }

 Cache.Current.AddToCache(o,key)
 Cache.Current.GetFromCache(key)

Issue
The above code only guaranteed if running in a single threaded environment or in other word its not thread safe.

Thread Safe Lazy Initialization
public class Cache
 {
  private static Cache cache = null;
  private static Object initLock = new object();

  static Cache(){}

  public static Cache Current
  {
   if (cache == null)
   {
    CreateInstance();
   } 
   return cache; 
  }
  
  private static void CreateInstance()
  {
   lock(initLock){
    if (cache == null)
     cache = new Cache();
   }
  }
  
  public static void AddToCache(Object o, Object key)
  {
   //Write logic to add to cache
  }
  
  public static object GetFromCache(Object key)
  {
   //Write logic to add to cache
  }
 }

 Cache.Current.AddToCache(o,key)
 Cache.Current.GetFromCache(key)

In the above code after the initial creation has happended the lock statement will never be executed.

Few Important Points on Singleton
• .Net singelton is scoped on an App Domain not process
• Singleton objects live forever so if they are expensive in terms of memory footprint they will continue to do so until the application dies as the type itself holds on to a strong reference.
• Hard to derive with. You can’t easily derive from a singleton since the constructor is private and thus the type is effectively sealed, making the constructor protected can offer some possibility of deriving from it although the derived class will not be able to have a private constructor.

Dec 1, 2011

Observer Pattern - Don't call us, we'll call you!

This is used whenever one or more objects (referred as observers) need to be notified when things change to the other object (referred as subject).

Simplest Solution 
Have subject notify observer when its data change. In this case you will pass reference of the observer class to the subject, so whenever subject wants to notify it can call objerver's notify me

 public class Subject
 {
  private Observer _observer;

  public Subject(Observer observer)
  {
   _observer = observer;
  } 

  public void DoWork(string desc)
  {
   
   Console.WriteLine( "Working on " + desc + "..." );
   Thread.Sleep( 3000 );
   Console.WriteLine( "Finished " + desc );
   _observer.NotifyOfWork( desc );
   Console.WriteLine();
   Thread.Sleep( 1000 );
  }
 }
 
 public class Observer
 {
  internal void NotifyOfWork(string desc)
  {
   Console.WriteLine( "Great " + desc + " is done" );
  }
 }
 
 public class Program
 {
  private static void Main()
  {
   Observer observer = new Observer();
   Subject subject = new Subject( observer);
   subject.DoWork( "Do some work" );
   subject.DoWork( "Do some more work" );
  }

 }

Issue with the above solution 
In the above solution Subject class is very tightly coupled with Observer. We have to add new code to add a new Observer. Also Observer cannot be added or removed dynamically.

Decoupling Subject and Observer
 


 public class Subject
 {
  private List observers = new List();

  public void AddObserver(IObserver obs)
  {
  observers.Add( obs );
  }

  public void RemoveObserver(Observer observer)
  {
  observers.Remove(observer);
  }

  public void Notify(string desc)
  {
  // Notify the observers by looping through all the registered observers.
  foreach(IObserver observer in observers)
   {
   observer.NotifyOfWork(desc);
   }
  }

  public void DoWork(string desc)
  {
   Console.WriteLine( "Working on " + desc + "..." );
   Thread.Sleep( 3000 );
   Console.WriteLine( "Finished " + desc );

   Notify( desc );

   Console.WriteLine();
   Thread.Sleep( 1000 );
  }
 }

 public class Observer1 : IObserver
 {
  internal void NotifyOfWork(string desc)
  {
   Console.WriteLine( "Great " + desc + " is done. This is notification from Observer1" );
  }
 }

 public class Observer2 : IObserver
 {
  internal void NotifyOfWork(string desc)
  {
   Console.WriteLine( "Great " + desc + " is done. This is notification from Observer2" );
  }
 } 
 
 public interface IObserver
 {
  void NotifyOfWork(string desc);
 }

 public class Program
 {
  private static void Main()
  {
   Observer1 observer1 = new Observer1();
   Observer2 observer2 = new Observer2();

   Subject subject = new Subject();
   subject.AddObserver( observer1 );
   subject.AddObserver( observer2 );

   subject.DoWork( "Do some work" );
   subject.DoWork( "Do some more work" );
  }
 }

In the above solution there is abstract coupling between Subject and Observer. Subject doesn't know the concrete class of any observer. We can add new observer without modifying subject. The notification that subject sends needn't specify the receiver. The notification is broadcast to all interested object that subscribed to it. The subject doesn't care how many interested objects exist; its only responsibility is to notify its observers. This gives you the freedom to add and remove observers at any time. It's up to the observer to handle or ignore a notification. So the solution is open for extension, but closed for modification. "O" (open/closed principle) in "SOLID".

Issue with the previous solution 
All my observer need to implement a common Interface. Also we have to write code to add/remove observer.

Even Cleaner Solution


 public delegate void WorkCompletedDelegate(string desc);

 public class Subject
 {
  public event WorkCompletedDelegate WorkCompleted;

  public void DoWork(string desc)
  {
   Console.WriteLine( "Working on " + desc + "..." );
   Thread.Sleep( 3000 );
   Console.WriteLine( "Finished " + desc );
   if (WorkCompleted != null)
   {
    WorkCompleted( desc );
   }
   Console.WriteLine();
   Thread.Sleep( 1000 );
  }
 }
 
 public class Observer1 
 {
  internal void NotifyOfWork(string desc)
  {
   Console.WriteLine( "Great " + desc + " is done. This is notification from Observer1" );
  }
 }
 
 public class Observer2 
 {
  internal void SubjectIsDone(string desc)
  {
   Console.WriteLine( "Great " + desc + " is done. This is notification from Observer2" );
  }
 }
 
 public class Program
 {
  private static void Main()
  {
   Observer1 observer1 = new Observer1();
   Observer2 observer2 = new Observer2();

   Subject subject = new Subject();
   subject.WorkCompleted = observer1.NotifyOfWork;
   subject.WorkCompleted = observer2.SubjectIsDone;

   subject.DoWork( "Do some work" );
   subject.DoWork( "Do some more work" );
  }
 }
 

Create a Custome valueprovider

Value providers are used by the model binding system in MVC to populate the values of model objects. MVC 3.0 includes value providers for several common value sources
System.Web.Mvc.FormValueProviderFactory
System.Web.Mvc.HttpFileCollectionValueProviderFactory
System.Web.Mvc.QueryStringValueProviderFactory
System.Web.Mvc.RouteDataValueProviderFactory

Decompile System.Web.Mvc.DefaultModelBinder, to review how BindProperty/BindModel (calls ContainsPrefix(text) on the value provider) and BindModel (GetValue) method uses Value Provider for populating model objects.

Below I have created a CookieValueProviderFactory derived from ValueProviderFactory which has a abstract method to GetValueProvider. In this case this gets my custome CookieValueProvider which implements IValueProvider (bool ContainsPrefix(string prefix) and System.Web.Mvc.ValueProviderResult GetValue(string key))

 public class CookieValueProviderFactory : ValueProviderFactory
    {
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            return new CookieValueProvider(controllerContext.HttpContext.Request.Cookies);
        }

        private class CookieValueProvider : IValueProvider
        {

            private readonly HttpCookieCollection _cookieCollection;

            public CookieValueProvider(HttpCookieCollection cookieCollection)
            {
                _cookieCollection = cookieCollection;
            }

            public bool ContainsPrefix(string prefix)
            {
                return _cookieCollection[prefix] != null;
            }

            public ValueProviderResult GetValue(string key)
            {
                HttpCookie cookie = _cookieCollection[key];
                return cookie != null ?
                           new ValueProviderResult(cookie.Value,
                                       cookie.Value,
                                       CultureInfo.CurrentUICulture)
                           : null;
            }
        }
    }

Then I add this to the ValueProviderFactories like this

 protected void Application_Start()
 {
  ValueProviderFactories.Factories.Add(new CookieValueProviderFactory());
 }

To test this I added cookies and in the Action this was automatically binded.

 private void AddCookie(IUserData userData)
 {
  HttpContext.Response.Cookies.Add(
   new HttpCookie("somethingToCookies", "Anything")
   );
 }
 
 public ActionResult CreateEmployee(string somethingToCookies)
 {
        }
 

Nov 30, 2011

Custome TempData Provider

Life span of TempData object is only till the subsequent request, or until the item is removed explicitly. This is useful when you want to pass data to another view that you will be redirecting to, rather than rendering to. By default, TempData is stored in the session using SessionStateTempDataProvider. So if you want to switch away from the default Session-State Mode, and use State Server Mode or SQL Server Mode, you need to store TempData objects which can be serializable.

You can also specify a custome temp data provider by setting TempDataProvider property of the controller.
public EmployeeController()
        {
            TempDataProvider = new CustomeTempDataProvider();
        }
 

CustomeTempDataProvider just need to implement ITempDataProvider. Refer to the sample code. In this example I am saving/loadion temp data to/from HttpContext.Current.Cache.

public class CustomeTempDataProvider : ITempDataProvider

    {
        internal string TempDataSessionStateKey = "__ControllerTempData";

        public IDictionary LoadTempData(ControllerContext controllerContext)
        {
            string userIdentifier = controllerContext.HttpContext.Request.UserHostAddress;

            HttpContext current = HttpContext.Current;
            if (current != null)
            {
                Dictionary dictionary = HttpContext.Current.Cache[TempDataSessionStateKey + userIdentifier] as Dictionary;
                if (dictionary != null)
                {
                    HttpContext.Current.Cache.Remove(TempDataSessionStateKey + userIdentifier);
                    return dictionary;
                }
            }
            return new Dictionary(StringComparer.OrdinalIgnoreCase);
        }

        public void SaveTempData(ControllerContext controllerContext, IDictionary values)
        {
            string userIdentifier = controllerContext.HttpContext.Request.UserHostAddress;

            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            HttpContext current = HttpContext.Current;
            bool flag = values != null && values.Count > 0;
            if (current == null)
            {
                if (flag)
                {
                    throw new InvalidOperationException("SessionStateTempDataProvider_SessionStateDisabled");
                }
            }
            else
            {
                if (flag)
                {
                    HttpContext.Current.Cache[TempDataSessionStateKey + userIdentifier] = values;
                    return;
                }
                if (HttpContext.Current.Cache[TempDataSessionStateKey + userIdentifier] != null)
                {
                    HttpContext.Current.Cache.Remove(TempDataSessionStateKey + userIdentifier);
                }
            }
        }
    }
 

How Default Model Binder works under the hood

If you have a requirement to write a custom model binding by implementing interface IModelBinder, then it's better to have a peek on DefaultModelBinder which is implemented in System.Web.Mvc. There is a lot which happens in this class and for most of the cases I prefer to create my custom model binder by deriving from DefaultModelBinder. In this way I can override whatever I need to and rest I can get for free.

There is a very less documentation around DefaultModelBinder so to find out what happens under the hood I decompiled System.Web.Mvc.DefaultModelBinder. Here are some of the important methods

  • BindModel - Only Member of IModelBinder interface. This binds simple as well as complex model.
  • BindComplexModel - This Creates Model by calling CreateModel and then call BindComplexElementalModel which calls BindProperties.
  • CreateModel - This create an instance of Model Type which you specify as a parameter type in the controller. So in the particular case CreateModel will return an object of type Employee.
    [HttpPost]
        public ActionResult EmployeeList(Employee employee)
       
    one case in which I had to override this was when I had a requirement to support for Interface type parameter. Refer to my posting on custom model binding
  • BindProperties - Binds all the properties of the model class by using controller context and binding context. This is the place where lot of magic happens. In the above case this will loop through all the properties of Employee and then bind from the controller context. This is one of the best part of default model binder which saves lot of development time. So for example it will bind the value of the property from HttpContext.Request.Form, which is collection of form variables. By default there are five ValueProviders:ChildActionValueProvider, FormValueProvider, RouteDataValueProvider, QueryStringValueProvider, HttpFileCollectionValueProvider.
  • BindProperty Calls GetPropertyValue which call BindModel which calls BindSimpleModel which gets the value.

In case of filters, DefaultModelBinder creates the Model object and in the filter you can access this model object using filterContext.ActionParameters[key] and populates the model object. In this case no binding happens in the DefaultModelBinder. Put a break point at the following location CreateModel, BindModel in the DefaultModelBinder and in your filter actionexecuting. You will notice that BindModel is called first and then CreateModel which creates the model object and then the filter action will be called. In filter action you can access the model object which CreateModel created using filterContext.ActionParameters[key]


The ModelBindingContext object is created and populated by whoever calls into the BindModel() method. If the model is coming in as an argument to your action method, this is done by ControllerActionInvoker.GetParameterValue(), and the ModelName property will be set to the name of the parameter (unless overridden by [Bind(Prefix = ... )]).

ModelBindingContext bindingContext = new ModelBindingContext() {
  FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified 
  ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
  ModelName = parameterName, 
  ModelState = controllerContext.Controller.ViewData.ModelState, 
  PropertyFilter = propertyFilter,
  ValueProvider = controllerContext.Controller.ValueProvider 
 };
 

If the model is being updated via UpdateModel(), the ModelBindingContext object is created by the UpdateModel() method itself. The ModelName parameter will be the prefix argument passed to UpdateModel().

Nov 16, 2011

How to persist Model State from a controller action using Action Filter

To persist ModelState from a controller action I created a filter called StateManagementFilter

    public class StateManagementFilter : ActionFilterAttribute
    {
        #region Constructor

        /// 
        /// 
        /// 
        /// This will reset state before action is executed.         /// This will save action state after it's executed        /// User can access/store state by the type        public StateManagementFilter(bool resetState = false, bool saveState = true, string stateType= "")
        {
            StateType = stateType;
            ShouldResetState = resetState;
            ShouldSaveState = saveState;

            //To avoid sending a user someone else’s state, we’ll need a way of uniquely identifying users.
            //Here I am using SessionID which may not be perfect always so we can use any shot of identification (like UserID) which uniquely identifies an User.
            HttpContext current = HttpContext.Current;
            UserIdentifier = "UserIdentifier" + current.Session.SessionID;
            
            if (resetState)
                ResetUserState();
        }

        #endregion

        #region ActionFilterAttribute Override

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.Controller.ViewData.Model != null && ShouldSaveState)
                SetUserState(filterContext.Controller);
            base.OnActionExecuted(filterContext);
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!ShouldResetState)
                filterContext.Controller.ViewData.Model = GetUserState(filterContext.Controller);
            base.OnActionExecuting(filterContext);
        }

        #endregion

        #region Private Property

        private string StateType { get; set; }
        private string UserIdentifier { get; set; }
        private bool ShouldResetState { get; set; }
        private bool ShouldSaveState { get; set; }

        #endregion

        #region Private Method

        private void ResetUserState()
        {
            HttpContext.Current.Cache.Remove(StateType + UserIdentifier);
        }


        /// 
        /// This stores the model object in the cache. For simplicity I am using web caching mechanism but we can use any caching framework 
        /// 
        ///         private void SetUserState(ControllerBase controller)
        {
            //If model object need to persisted only till the subsequent requests then TempData can be used
            //controller.TempData["__UserStateData"] = controller.ViewData.Model;
            System.Web.HttpContext.Current.Cache[StateType + UserIdentifier] = controller.ViewData.Model;
        }

        /// 
        /// This retrieves state from the cache
        /// 
        ///         /// 
        private object GetUserState(ControllerBase controller)
        {
            //return controller.TempData["__UserStateData"];
            return HttpContext.Current.Cache[StateType + UserIdentifier];
        }

        #endregion

    }


In the controller I can use this filter like like this

[StateManagementFilter(true, true, "EmployeeList")]
        public ActionResult EmployeeList()
        {
            return View(new Employee());
        }

        [HttpPost, StateManagementFilter(false, true, "EmployeeList")]
        public ActionResult EmployeeList(Employee employee)
        {
            Employee employee1 = (Employee) ViewData.Model;
            return View(employee);
        }

In the first controller action I am saving the state which will mean that the next controller action will get the View Data Model from the first controller action. So in the above example the new Employee object which is getting created in the first controller action can be available in the second controller action.

Also by specifying the type of state, controller can specify which state it will be interest in.

This will be mostly useful when you perform some costly business logic to create a model object in one controller action and would like to persist. So by using this filter you can save this in cache.

This can also be used for redirect call. For example you perform some business logic and then you decide based on some condition that this need to be redirected to different action. Although for this particular case it will be better to use TempData as the life span of TempData object is onli till the subsiquest request.Refer to the commented code in SetState/GetState. For using temp data in web farm you may need to implement custome temp data provider.

Nov 14, 2011

Custom Model Binder on Interface Type

Its very common to use Default Model Binder which maps a browser request to a data object, something like this.

public ActionResult EmployeeList(Employee employee)
{
    return View();
}


One down side of this is that during unit test you have to construct an object from employee class. It will be nice if we can have interface parameter type something like this. In this case, unit test doesn't have to bother on the concrete implementation of Employee class.

public ActionResult EmployeeList(IEmployee employee)
{
    return View();
}

But unfortunately this will throw exception "Cannot create an instance of an interface". The reason for this is that during binding it try to create an instance of model type which in this case is an interface and hence it throws exception. You can easily decompile System.Web.Mvc.DefaultModelBinder and look at method CreateModel where this is failing.

To get away with the issue I created an InterfaceTypeModelBinder. The constructor of the InterfaceTypeModelBinder takes ModelType as aparameter.

public class InterfaceTypeModelBinder : DefaultModelBinder
{
        private Type ModelType { get; set; }

        public InterfaceTypeModelBinder(Type modelType)
        {
            ModelType = modelType;
        }

        protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
        {
            Type type = GetModelType(bindingContext.ModelType);
            Debug.WriteLine(Environment.StackTrace);
            return Activator.CreateInstance(type);
        }

        private  Type GetModelType( Type modelType)
        {
            Type type = modelType;

            if (ModelType != null)
                type = ModelType;

            if (modelType.IsGenericType)
            {
                Type genericTypeDefinition = type.GetGenericTypeDefinition();
                if (genericTypeDefinition == typeof(IDictionary<,>))
                {
                    type = typeof(Dictionary<,>).MakeGenericType(type.GetGenericArguments());
                }
                else
                {
                    if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IList<>))
                    {
                        type = typeof(List<>).MakeGenericType(type.GetGenericArguments());
                    }
                }
            }
            return type;
        }       
}
        
Now in my Global.asax.cs file I can register my binder like this
protected void Application_Start()
{
     AreaRegistration.RegisterAllAreas();

     RegisterGlobalFilters(GlobalFilters.Filters);
     RegisterRoutes(RouteTable.Routes);
     ModelBinders.Binders[typeof(IEmployee)] = new InterfaceTypeModelBinder(typeof(Employee));
     ModelBinders.Binders[typeof(ICustomer)] = new InterfaceTypeModelBinder(typeof(Customer));
}


By doing this I can use IEmployee or ICustomer or any type as a parameter as long as it is registered.