Jan 18, 2012

Mobile Capable View Engine- Custome View Engine

One of the nice feature of ASP .NET MVC framework is its Extensibility. I created a custom view engine which changes view location based on the device from where its being accessed.

In the following code I update view name with mobile specif view, if the request is being originating from mobile devise

 public class MobileCapableRazorViewEngine : RazorViewEngine
    {
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            if(IsMobileDevice(controllerContext))
   {
    viewName = viewName + ".mobile";
    masterName = masterName + ".mobile"
   }
        }
 }
 
 private static bool IsMobileDevice(ControllerContext controllerContext)
 {
  //ASP.NET’s built-in browser detection support may not be sufficient for all applications specifically in case of latest devices
  //add the open source 51Degrees.mobi Foundation library to your project
  //you can also use UserAgent controllerContext.HttpContext.Request.UserAgent
  return controllerContext.HttpContext.Request.Browser.IsMobileDevice;
 }


And in the global.asax remove the default view engine and add our custome view engine.

 //Remove default RazorViewEngine and add MobileCapableRazorViewEngine
 ViewEngines.Engines.Remove(ViewEngines.Engines.OfType().First());
 ViewEngines.Engines.Add(new MobileCapableRazorViewEngine());

 

Similar approach can be taken for FindPartialView.

Jan 17, 2012

Pipe and Filters

Break large transformation into small transform which lowers the complexity of individual transform. It also increases their potential for reuse.

Filter

A filter takes a message from its input, applies a transformation, and sends the transformed message as output. Filters implement simple transformation or transfer functions to  perform operations such as: Conversion, enrichment, filtering, batching, or consolidation.

Pipes
Pipes transport and buffer (data integrity/synchronization) messages between filters.

Key Points
1.The single-filter configuration implements the transformation by using one specialized component. The one hop that exists between input and output and the elimination of the interfilter communication translate into low latency and overhead.
2. The key tradeoffs in choosing between a combination of generic filters and a single specialized filter are reusability and performance.
3. Filters must not be dependent on other filters.

Simple Implementation

public interface IFilter
    {
        T Execute(T input);
    }

    public class Pipeline
    {
        private readonly List< IFilter> _filters = new List< IFilter>();

        public void Register(IFilter filter)
        {
            _filters.Add(filter);
        }

        public T Execute(T input)
        {
            T current = input;

            try
            {
                foreach (IFilter filter in _filters)
                {
                    current = filter.Execute(current);
                }
            }
            catch (Exception exception)
            {
                //Add error handling logic
                EventLog.WriteEntry(GetType().FullName,exception.Message);
                throw;
            }
            return current;
        }
    }

public class LowerCaseString : Filter1BaseClass,IFilter
    {
        protected override string Process(string input)
        {
            return input.ToLower();
        }
    }

    public class UpperCaseString : Filter1BaseClass,IFilter
    {
        protected override string Process(string input)
        {
            return input.ToUpper();
        }
    }

var input = "Test";
 Console.WriteLine("Input: {0}", input);
 Pipeline pipeline = new Pipeline();
 pipeline.Register(new LowerCaseString());
 pipeline.Register(new UpperCaseString());
 string output = pipeline.Execute(input);
 Console.WriteLine("Output: {0}", output);