cheap oakleys replica michael kors bags cheap christian louboutin online elite jerseys wholesale cheap nfl jerseys discount ray bans cheap michael kors cheap ray bans replica oakleys wholesale replica michael kors wholesale oakley sunglasses cheap fake ray bans cheap jerseys china cheap christian louboutin outlet fake cheap oakleys cheap oakleys cheap jerseys sale cheap christian louboutin discount oakleys wholesale nfl jerseys cheap michael kors handbags michael kors handbags discount christian louboutin cheap jerseys michael kors on sale discount ray bans wholesale jerseys cheap michael kors fake oakleys online cheap michael kors bags replica ray bans discount ray bans authentic jerseys cheap christian louboutin cheap oakleys cheap oakleys outlet nfl jerseys red bottoms shoes on sale cheap ray bans cheap nfl jerseys cheap replica oakleys michael kors on sale cheap christian louboutin outlet Cheap Elite Jerseys cheap michael kors cheap ray bans cheap jerseys free shopping cheap fake oakleys cheap oakleys sale cheap michael kors outlet ray bans shop fake cheap oakleys cheap authentic nike jerseys christian louboutin online fake cheap oakleys fake oakleys store cheap jerseys wholesale cheap christian louboutin replica oakleys cheap jerseys wholesale cheap replica oakleys michael kors handbags wholesale jerseys china discount nhl jerseys wholesale replica michael kors cheap ray bans cheap jerseys cheap fake oakleys fake oakleys cheap michael kors store cheap ray bans wholesale oakleys jerseys wholesale christian louboutin outlet cheap mlb jerseys oakley sunglasses authentic jerseys christian louboutin outlet cheap replica oakleys wholesale authentic jerseys wholesale mlb jerseys michael kors handbags cheap jerseys online shopping cheap nhl jerseys michael kors bags cheap fake oakleys cheap jerseys from china cheap fake oakleys 2016 cheap fake oakleys cheap michael kors cheap discount ray bans fake cheap oakleys cheap jerseys free shopping cheap christian louboutin online wholesale nfl jerseys cheap jerseys from china wholesale christian louboutin wholesale mlb jerseys official jerseys fake cheap oakleys cheap michael kors handbags wholesale jerseys cheap wholesale jerseys cheap fake oakleys oakley sunglasses cheap discount oakleys oakleys sunglasses usa cheap michael kors online wholesale and retail oakleys cheap michael kors outlet cheap wholesale jerseys wholesale cheap jerseys china cheap replica oakleys fake oakleys online authentic jerseys wholesale ray bans fake cheap oakleys jerseys wholesale replica ray bans wholesale sunglasses wholesale mlb jerseys cheap cheap nfl jerseys cheap michael kors outlet cheap fake ray bans cheap oakleys sale cheap fake ray bans oakleys sunglasses michael kors bags fake cheap oakleys fake cheap oakleys authentic wholesale jerseys nhl jerseys cheap michael kors outlet cheap oakleys online wholesale jerseys fake ray bans online store michael kors handbags outlet wholesale jerseys china fake ray bans ray bans outlet cheap christian louboutin cheap nba jerseys cheap ray bans cheap ray bans wholesale nfl jerseys wholesale sunglasses michael kors bags outlet cheap ray bans on sale fake cheap oakleys cheap nfl jerseys cheap nhl jerseys cheap oakleys cheap jerseys cheap fake oakleys michael kors outlet cheap jerseys store fake ray bans christian louboutin shoes discount nba jerseys michael kors for sale cheap fake oakleys fake ray bans sunglasses cheap michael kors handbags oakley sunglasses michael kors handbags michael kors on sale fake cheap oakleys cheap nfl jerseys replica oakleys cheap oakleys outlet cheap oakleys cheap authentic nfl jerseys paypal cheap fake oakley sunglasses cheap oakleys cheap jerseys paypal
Dependency Injection » Inder Singh's Blog
Mar 172013
 

I will be writing more introductory posts on my experience in using Castle Windsor Inversion of Control Container and Dependency Injection concepts later but this post is a solution to one of the problems I encountered which required custom lifestyle for Castle Windsor. Inversion of Control and Castle Windsor principles are pre-requisites to be able to follow this blog post, so read on if you are familiar with above mentioned concepts and are stuck with a similar problem in your implementation….

The application is a WCF Service web application where Castle Windsor Container injects dependencies into WCF service classes, to be more specific dependencies here are Repository classes which use NHibernate to access data from database. The repositories make use of NHibernate ISession which also gets injected by Castle Windsor. The application initially only consisted of services using data access code and the NHibernate Session was configured to use PerWcfOperation lifestyle so that only one NHibernate Session object is instantiated for a service method call. Hence, if service method makes use of multiple repositories then all of the repositories share the same NHibernate Session object injected by DI Container. I will refer to PerWcfOperation lifestyle as out of the box lifestyle, although it is not part of standard Castle Windsor but available as part of WCF Integration Facility. The application evolved and there was a need for a web page as well as an Http Handler to access data but the WcfPerOperation lifestyle is not available within the context of web request and hence any attempt to resolve the NHibernate Session failed. The out of the box lifestyles are set at compile time so either I could make the data access code work within the Web by changing the lifestyle to PerWebRequest or within the Wcf service methods by setting the lifestyle to PerWcfOperation but not both at the same time. Hence, there was a need for a hybrid lifestyle for the NHibernate Session dependency object where the lifestyle is determined at runtime based on whether the data access code is being executed within a Web Request or WcfOperation context.

I wanted a very simple solution which solves the problem without any bells and whistles. I did find some code on web which addressed the issue but it was little bit more complicated and the module never made it past the alpha version.

The basic understanding of inner workings of out of the box lifestyles in Castle Windsor (or its facilities) provides an insight into achieving the desired hybrid lifestyle. DI container manages the lifespan of registered components, if the component does not have a transient lifestyle the instance needs to be stored in some kind of cache for future resolve requests for that component. So, let’s look into the following out of the box lifestyles
• PerWebRequest – DI Container stores components of this lifestyle in HttpContext which is available only within the context of a web request.
• PerWcfOperation – Components of this lifestyle are stores in Wcf OperationContext which is available only within the context of a Wcf operation

An attempt to resolve an object of lifestyle PerWebRequest fails outside a web request and similarly an attempt to resolve an object of lifestyle PerWcfOperation fails outside Wcf operation. Now our solution for hybrid lifestyle relies on these out of the box lifestyles and requires only a handful of classes. It determines the lifestyle of the component dynamically at runtimes based on the following conditional logic in order:
• Set Lifestyle to PerWcfOperation if OperationContext is available
• Set Lifestyle to PerWebRequest if HttpContext is available
• Set Lifestyle to Transient which does not store the resolved component and creates a new component on each resolve request.

The above mentioned logic is wired into the Castle Windsor by implementing following two classes:
• HybridLifestyleScopAccessor – An implementation of Castle.MicroKernel.Lifestyle.Scoped. IScopeAccessor and contains the code for above mentioned conditional logic.
• TransientScopAccessor – This again is an implementation of Castle.MicroKernel.Lifestyle.Scoped.IScopeAccessor which will be used if neither HttpContext nor OperationContext are available.

There is no need to implement accessors for PerWcfOperation and PerWebRequest because they are already available out of the box.

/// <summary>     
/// Custom LifeStyle to automatically detect the context in which the application is being used and return appropriate scope for the objects. Following is the order in which scopes are detected and the first one found is returned:     
/// - WCF Operation     
/// - Web Request     
/// - Transient
/// </summary>
/// <remarks>        
/// <para>     
/// No new scope is implemented, it just  provides a Hybrid model for scopes provided by Castle Windsor and WCF Integration Factility.     
/// </para>     
/// <para>      
/// Primarily introduced so that the Data Access code using NHibernate Sessions can work within WCF Operation as well as Web Request.     
/// </para>     
/// <para>     
/// Following configuration must be added to web.config for the WebRequest Lifetime Scope to work:     
/// <configuration>     
///     <system.webServer>     
///         <modules>     
///             <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />     
///         </modules>     
///     </system.webServer>     
/// </configuration>     
/// </para>     
/// </remarks> 
public class HybridLifeStyleScopeAccessor : IScopeAccessor
{
   private readonly IScopeAccessor _WcfOperationScopeAccessor = new Castle.Facilities.WcfIntegration.Lifestyles.WcfOperationScopeAccessor();
   private readonly IScopeAccessor _WebRequestScopeAccessor = new Castle.MicroKernel.Lifestyle.WebRequestScopeAccessor();
   private readonly IScopeAccessor _TransientScopeAccessor = new TransientScopeAccessor();

  ///<summary> 
  /// If Wcf Opertaion Context is available then returns WcfOperation Lifetime Scope
  /// Else If HttpContext is avilable then return WebRequest Lifetime Scope
  /// Else Returns Transient LifetimeScope
  /// </summary>
  public ILifetimeScope GetScope(Castle.MicroKernel.Context.CreationContext context)
  {
     if (OperationContext.Current != null)
       return this._WcfOperationScopeAccessor.GetScope(context);
     else if (HttpContext.Current != null)
       return this._WebRequestScopeAccessor.GetScope(context);
     else
       return this._TransientScopeAccessor.GetScope(context);
  }

#region IDisposable
   private bool disposed = false;

   protected virtual void Dispose(bool disposing)
    {
      if (!disposed)
       {
          if (disposing)
           {
              this._TransientScopeAccessor.Dispose();
              this._WcfOperationScopeAccessor.Dispose();
              this._WebRequestScopeAccessor.Dispose();
           }
           disposed = true;
        }
    }

  public void Dispose()
   {
       Dispose(true);
       GC.SuppressFinalize(this);
   }
#endregion
}

TransientScopeAccessor is a custom accessor which also needs to be implemented

/// <summary>
/// Used by the HybridLifeStyleScopeAccessor class to provide the Transient LifeStyle as fallback
/// </summary>
public class TransientScopeAccessor : IScopeAccessor
{
  public ILifetimeScope GetScope(Castle.MicroKernel.Context.CreationContext context)
   {
       return new DefaultLifetimeScope();
   }

 #region IDisposable

 private bool disposed = false;

 protected virtual void Dispose(bool disposing)
 {
   if (!disposed)
    {
       disposed = true;
    }
  }

 public void Dispose()
 {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
  #endregion
 }

A component can be registered with this Hybrid Lifestyle using the following line of code:

container.Register(Component.For().LifestyleScoped())