May 24, 2012

Custom Controller Factory

Constructor Injection is the DI technique of passing an object's dependencies to its constructor. But this by default will not work with Mvc unless you have a parameterless constructor also defined. If you try to run, it will throw error stating that “No parameterless constructor is defined for this object”. A way to get around this and have DI is by defining both parameterless constructor as well as one with which you want to have dependency.

public class ProductController : Controller
    {
        #region Constructor
        
        public ProductController()
            : this(new ProductModel())
        {
        }

        public ProductController(IProductModel productModel)
        {
            if (productModel == null)
                throw new ArgumentNullException("productModel");
            ProductModel = productModel;
        }

        private IProductModel ProductModel { get; set; } 

        #endregion

The other way to achieve this is by defining CustomeControllerFactoryWithoutDefaultConstructor something like this

public class CustomeControllerFactoryWithoutDefaultConstructor : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return Activator.CreateInstance(controllerType, new ProductModel()) as IController;
        }
    }

And then register this in Global.asax:

ControllerBuilder.Current.SetControllerFactory(typeof(CustomeControllerFactoryWithoutDefaultConstructor));

Dependency Injection DI/IoC

Dependency Injection (DI) means that this is done without the object intervention. In other words the object dependency is on interfaces and not on concrete objects. This promotes greater reusability, easier maintainability, and mockability unit test. Thsi is also referred as Inversion of Control (IoC) which means that objects do not create other objects on which they rely to do their work. Instead, they get the objects that they need from an outside source (for example, an xml configuration file).

Constructor Injection
Constructor Injection is the DI technique of passing an object's dependencies to its constructor.

 public class ProductController 
 {
  public ProductController(IProductModel productModel)
  {
   if (productModel == null)
    throw new ArgumentNullException("productModel");
   ProductModel = productModel;
  }

From the above it is clear to the developer invoking the object, which dependencies need to be given to the ProductController object for proper execution.

Consider a case where you have lots of methods with no dependencies and you are adding a new method that does have a dependency on IProductModel. So one way is to change the constructor to use Constructor Injection, but this will require changes to all existing constructor calls. So alternatively, you could just add a new constructor that takes the dependency.

 public class ProductController 
 {
  public ProductController()
  {
  
  }
  public ProductController(IProductModel productModel)
  {
   if (productModel == null)
    throw new ArgumentNullException("productModel");
   ProductModel = productModel;
  }

Now some one can argure how does a developer easily know when to use one constructor over the other.

The other case is, if the dependency is very expensive to create, why should it be created and passed to the constructor when it may only be used rarely? "Setter Injection" is another DI technique that can be used in situations such as this.

Setter Injection
In this case dependencies are set onto public properties exposed by the object in need.

 public class ProductController 
 {
  public ProductController()
  {
  
  }
  
  public IProductModel ProductModel { get; set; } 

Few things to consider here
 . In this case it does not make very clear when dependency need to be create as in case of constructor Injection.
. Also note that in constructor Injection we an exception is thrown if the dependency is not set immediately, where as with Setter Injection, an exception isn't thrown until a method actually attempts to use the dependency.

Injectors
Now someone has to create the dependency. One of the approach is to use "DI controller". In the following Mvc example I have two constructors default and the other with parameter. The framework will use default constructor where as for unit testing one can use the one which has parameter so that it can be easily mockable.

 public class ProductController : Controller
    {
        #region Constructor
        //
        // GET: /Product/
        public ProductController()
            : this(new ProductModel())
        {
            TempDataProvider = new CustomeTempDataProvider();
        }

        public ProductController(IProductModel productModel)
        {
            if (productModel == null)
                throw new ArgumentNullException("productModel");
            ProductModel = productModel;
        }

        public IProductModel ProductModel { get; set; } 

Even if "controller" is not well defined if you see at a high level in any properly tiered architecture "controller" layer always exists. For example in ASP.NET, the code-behind page acts as a controller layer.

The other approach is to use DI Containers. There are some frameworks (Spring .NET, Windsore) which allows you to define dependency injections within an XML file.

Apr 27, 2012

Wcf Operation Invoker - IOperationInvoker

Operation invoker is the last element in the WCF runtime which is invoked before the service implementation is reached – it’s the invoker responsibility to actually call the service operation on behalf of the runtime. This can be used to implement caching logic for expensive operations.

public class CachingOperationInvoker : Attribute, IOperationBehavior,IOperationInvoker
{
 readonly IOperationInvoker _originalInvoker;
 readonly double _cacheDuration;

 public CachingOperationInvoker(IOperationInvoker originalInvoker, double cacheDuration)
 {
  _originalInvoker = originalInvoker;
  _cacheDuration = cacheDuration;
 } 
 
 public double SecondsToCache { get; set; }
 
 #region Implementation of IOperationInvoker

 public object Invoke(object instance, object[] inputs, out object[] outputs)
 {
  ObjectCache cache = GetCache();

  string cacheKey = CreateCacheKey(inputs);
  CachedResult cacheItem = cache[cacheKey] as CachedResult;
  if (cacheItem != null)
  {
   outputs = cacheItem.Outputs;
   return cacheItem.ReturnValue;
  }
  object result = _originalInvoker.Invoke(instance, inputs, out outputs);
  cacheItem = new CachedResult { ReturnValue = result, Outputs = outputs };
  cache.Add(cacheKey, cacheItem, DateTimeOffset.UtcNow.Add(TimeSpan.FromSeconds(_cacheDuration)));

  return result;
 }
 
 #endregion
 
 #region Implementation of IOperationBehavior
 
 public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
 {
  dispatchOperation.Invoker = new CachingOperationInvoker(dispatchOperation.Invoker, SecondsToCache);
 }
 
 #endregion
Now you can easily decorate your operation with the attribute
  
 [CachingOperationInvoker(SecondsToCache = 100)]
    Product GetProduct(int id); 

One thing I would like to point out here is that the caching is happening at the server level which will mean that it will go through the wcf pipeline, the saving which we are doing here is the actual operation call. The other approach to consider here would be to come up with caching logic at the client side. Unlike REST services, SOAP services don’t have any standard way of defining caching options for their operations.

Apr 10, 2012

Conditional Cache for RESTful service

As per the HTTP specification, GET and HEAD shouldn’t have any side effects that would adversely effect the caching of the response, unless server prohibits caching. Most of the browser caches HTTP/200 responses, unless Expires, Pragma, or Cache-Control headers are present.

Just by having ETag or Last-Modified time, your GET method will be cached in the browser. You can easily test this using fiddler.

 In this post I am going to write a conditional cache logic based on ETag and/or LastModified. In the following code Product object has two additional fields : ETag and LastModifiedDate, based on this (both or eather) field, we will determine if we need to suppress Entity Body and accordingly set the response status to NotModified.

 
 public Product GetProductRestStyle(string id)
 {
  OutgoingWebResponseContext outgoingResponse = WebOperationContext.Current.OutgoingResponse;
  IncomingWebRequestContext incomingRequest = WebOperationContext.Current.IncomingRequest;

  //retrieve product object from any repository
  Product product = GetProduct(Convert.ToInt32(id));

  if(product == null)
  {
   outgoingResponse.SetStatusAsNotFound();
   return null;
  }

  //Product object contains LastModifiedDate and ETag, which we will compare in the incomingRequest 
  //and if it is same we will supress the response body
  CheckModifiedSince(incomingRequest, outgoingResponse, product.LastModifiedDate);
  CheckETag(incomingRequest, outgoingResponse, product.ETag);

  //Set LastModifiedDate and ETag on the outgoing response 
  outgoingResponse.ETag = product.ETag.ToString();
  outgoingResponse.LastModified = product.LastModifiedDate;

  //Give a cache hint
  //Resource will expire in 10 sec
  outgoingResponse.Headers.Add(HttpResponseHeader.CacheControl, "max-age=10");
  
  return product;
 }
 
 private static void CheckETag(IncomingWebRequestContext incomingRequest, OutgoingWebResponseContext outgoingResponse, Guid ServerETag)
 {
  string test = incomingRequest.Headers[HttpRequestHeader.IfNoneMatch];
  if (test == null)
   return;
  Guid? eTag = new Guid( test);
  if (eTag != ServerETag) return;
  outgoingResponse.SuppressEntityBody = true;
  outgoingResponse.StatusCode = HttpStatusCode.NotModified;
 }

 private static void CheckModifiedSince(IncomingWebRequestContext incomingRequest, OutgoingWebResponseContext outgoingResponse, DateTime serverModifiedDate)
 {
  DateTime modifiedSince = Convert.ToDateTime(incomingRequest.Headers[HttpRequestHeader.LastModified]);

  if (modifiedSince != serverModifiedDate) return;
  outgoingResponse.SuppressEntityBody = true;
  outgoingResponse.StatusCode = HttpStatusCode.NotModified;
  
 }


The above code will be useful in the following conditions:
In the case where the client cannot tolerate a stale cache and a "hint" is not good enough, they may issue a request to the server, if the cache is still fresh, the server will send a 304 "Not Modified" response with no entity body. The client can then safely source the data from it’s cache.

Another scenario is the case where the client abides by the caching hint, but the cache is expired. As opposed to simply throwing away the cache, the client can issue a Conditional GET to see if the cache is still good.

Mar 19, 2012

Wcf Message Inspector - IMessageInspector

You can use message inspector to log, inspect, modify or completely replace a message by implementing IClientMessageInspector (client side) or IDispatchMessageInspector (server side)
 #region IDispatchMessageInspector Implementation

 public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
 {
  //You can access the body of a Message only once, regardless of how it is accessed.
  //http://msdn.microsoft.com/en-us/library/ms734675.aspx
  request = LogMessage(request.CreateBufferedCopy(int.MaxValue));
  return null;
 }

 #endregion

 
Now this can be added through Endpoint/Service/Contract behavior
 
  public class LogMessageEndpointBehavior : Attribute, IEndpointBehavior
 {
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new LoggingMessageInspector());
        }

 }
 

Mar 1, 2012

WCF error handling using DataAnnotations Validator

ParameterInspector can also be used to validate DataMember in the data contract for the incoming request by using DataAnnotations Validator.

So suppose I have a DataContract defined something like this

 [DataContract]
    public class CompositeType
    {
        string stringValue = "Hello ";
        [DataMember]
        [Required(ErrorMessage = "Name is required")]
        [StringLength(20, MinimumLength = 1, ErrorMessage = "Name must have between 1 and 20 characters")]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

Refer to DataAnnotations Required and StringLength attribute. Now I want a generic Validator which inspects the parameter and does Validation using DataAnnotations.

 
 public class ValidatingParameterInspector : IParameterInspector
    {
        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState){}
  
        public object BeforeCall(string operationName, object[] inputs)
        {
   //So I loop through all the input parameters and validate it using DataAnnotations Validator
            foreach (var input in inputs)
            {
                if (input != null)
                {
                    ValidationContext context = new ValidationContext(input, null, null);
                    Validator.ValidateObject(input, context, true);
                }
            }
            return null;
        }
    }
And now you can add this to OperationBehavior or even endpoint behavior
 

 public class ValidatingParameterInspectorOperationBehavior : Attribute, IOperationBehavior
    {
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters){}
        public void Validate(OperationDescription operationDescription){}
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            ValidatingParameterInspector validatingParameterInspector = new ValidatingParameterInspector();
            dispatchOperation.ParameterInspectors.Add(validatingParameterInspector);
        }
    } 
So now before call reaches to the operation it will be inspected by BeforeCall where it will fail validation and raise exception. You can also raise custom FaultException

WCF error handling by implementing IErrorHandler

By implementing IErrorHandler you can control the fault message which is sent to the caller and perform error processing such as logging
  

 public class MyCustomeErrorHandler : IErrorHandler
    {

        public bool HandleError(Exception error)
        {
            Trace.TraceError(error.ToString());
            return true;
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
   //Log server error for troubleshooting error
   
   //you can customise fault exception as you want
            FaultException faultException = new FaultException("Server error encountered.);
            MessageFault messageFault = faultException.CreateMessageFault();
            fault = Message.CreateMessage(version, messageFault, faultException.Action);
        }

    }
We can now add this to ServiceBehavior
  

 public class MyCustomeErrorHandlerServiceBehavior : Attribute,IServiceBehavior
    {
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase){}

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters){}

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            IErrorHandler handler = new MyCustomeErrorHandler();
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(handler);
            }
        }
    }
 
Now this way your custome error handler will be used where you can put some friendly message which will be sent to the caller.

The other way is to catch your application error in your operation and then throw FaultException somethign like this
 

 public string GetData(int value)
 {
  try
  {
   throw new Exception("My Service Operation Error");
  }
  catch (Exception ex)
  {
   //Log your applocation exception
   throw new FaultException(new ApplicationException("My Custome Fault Messahe"),new FaultReason("some fault reason"));
  }
 }