Castle MicroKernel/Windsor QuickStart 2: LifeStyle and LifeCycle

…continued from part 1.

Objectives

In this Hands-On Lab, you will be introduced to the Castle MicroKernel/Windsor framework. In particular, you will:
  • Understand LifeStyle
  • Understand LifeCycle

System requirements

You must have the following items to complete this lab:
  • Microsoft Visual Studio 2008 SP1 (professional edition)

Prequisites

You must have the following skills to understand this lab:
  • Fundamental knowledge of software development in .NET 3.5
  • Basic knowledge of Castle

Understand LifeStyle

LifeStyle is a strategy that is related to an instance of a component. The supported lifestyles are:

  • Singleton: only one instance will be created for the whole life of the container. This is the default lifestyle.
  • Transient: for each request a new instance if the component is created
  • PerThread: for each thread there exists only one instance of a component
  • Pooled: Instances will be pooled to avoid unnecessary constructions
  • Custom: the instantiation of components is handled by your custom ILifestyleManager implementation

The default lifestyle is singleton. To indicate which lifestyle you want to use, you can use attributes to decorate the class:

[Transient]
public class CustomerRepository : ICustomerRepository
{

}

or in the configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
Castle.Windsor"
/>
</configSections>
<castle>
<components>
<component
id="customer.business"
service="CastleExample.ICustomerBusiness, CastleExample"
lifestyle="transient"
type="CastleExample.CustomerBusiness, CastleExample" />
<component
id="customer.repository"
service="CastleExample.ICustomerRepository, CastleExample"
lifestyle="transient"
type="CastleExample.MockCustomerRepository, CastleExample" />
</components>
</castle>
</configuration>

I prefer to do it in configuration because otherwise the code will be coupled again to the Castle container, or, in complicated projects, it may be handier to do it in code but in that case, create specific classes that are responsible for these configuration tasks, so that in your code you have as little as dependencies to Castle as possible.

So try this: add a transient lifestyle to the components in the configuration file, and to see the effect, modify the constructor of CustomerBusiness and add constructors to CustomerRepository and MockCustomerRepository as follows:

public class CustomerBusiness : ICustomerBusiness
{
private ICustomerRepository customerRepository;
public CustomerBusiness(ICustomerRepository customerRepository)
{
// using constructor injection the concrete customer repository is injected
this.customerRepository = customerRepository;
Console.WriteLine("CustomerBusiness constructor");
}

}

public class CustomerRepository : ICustomerRepository
{
public CustomerRepository()
{
Console.WriteLine("MockCustomerRepository constructor");
}

}

public class MockCustomerRepository : ICustomerRepository
{
public MockCustomerRepository()
{
Console.WriteLine("MockCustomerRepository constructor");
}

}

Modify Program.cs:

static void Main(string[] args)
{

// Use business
UseRegisteredBusiness();
UseRegisteredBusiness();
UseRegisteredBusiness();
}

If you run the application, you will notice that each constructor is only called once and so there is only one instance created of the components for all calls:

Change the configuration that components use the transient lifestyle, and then run the application again to see the difference:

Now for each call of the business component, the constructors are called, which means that new objects are created for each call.

Understand LifeCycle

On the other hand there is LifeCycle, which is a strategy that is related to the different phases of an instance. It means that we can implement a number of interfaces; and these implementations are executed at the right time. Out of the box there are two groups of lifecycles:

  • Commission: these are executed when the component is being created. Interfaces are:
    • Castle.Model.IInitializable
    • System.ComponentModel.ISupportInitialize
  • Decommission: these are executed when the component is being destructed. Interface is:
    • System.IDisposable

So, bottom line: if you implement one of these interfaces for your component, Castle will take care of calling your implementations at the right time. Notice that if you use these, the coupling to Castle container will be higher.

Advertisements

2 thoughts on “Castle MicroKernel/Windsor QuickStart 2: LifeStyle and LifeCycle

  1. Don’t use ServiceLocator. ServiceLocator is an anti-pattern, should be avoided and Windsor has a lot better ways to manage scenarios where you could be tempted to use ServiceLocator.

    • Ludwig Stuyck says:

      Thanks for the feedback, meanwhile I found out that you indeed better use constructor injection instead of ServiceLocator.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s