Making Transient as Default Lifestyle in Castle Windsor

6. August 2009

This is actually an answer to fellow blogger Jak Charlton, but I see a benefit in sharing it.

Casey pointed out that the default lifestyle should be transient. Even though I understand his reasonings, I am used to this way.

There is a solution for those who wants Transient as the default.

You know what? Yes, the events ! Here is how.

container.Kernel.ComponentModelCreated += new ComponentModelDelegate(Kernel_ComponentModelCreated);


void Kernel_ComponentModelCreated(Castle.Core.ComponentModel model)
{
	if (model.LifestyleType == LifestyleType.Undefined)
		model.LifestyleType = LifestyleType.Transient;
}

, ,

Implementing EnrichWith(of StructureMap) with Castle

15. July 2009

UPDATE: This facility made its way into Castle Microkernel, with name OnCreateFacility. I also made it possible to specify more than one actions.

In one of Joshua Flanagan's recent post he mentioned about how they handle application configuration and I have to say that I liked their way. I also liked how SM can post-modify an object created, and looked for a way to do it in Castle. As many other stuff, I was able to achieve the same effect with a custom Facility.

If I go further in the details, I had to catch ComponentCreated event of Kernel.

public class EnrichWithFacility:AbstractFacility
{
	public const string ExtendWithPropertyKey = "extendwith";
	protected override void Init()
	{
		Kernel.ComponentCreated += Kernel_ComponentCreated;
	}
	void Kernel_ComponentCreated(ComponentModel model, object instance)
	{
		if(model.ExtendedProperties.Contains(ExtendWithPropertyKey))
		{
			var action = model.ExtendedProperties[ExtendWithPropertyKey] as ExtendComponentDelegate;
			action(this.Kernel, instance);
		}
	}
}

Whenever a component is created, I will catch it and ask if there is any EnrichWith registered for the ComponentModel, and if there is any, invoke the action.

I also added a fluent registration extensions (Castle style!) in order to make it easy to register enrichments.

container.Register(Component.For<IService>().ImplementedBy<MyService>()
			 .EnrichWith((kernel, instance) => ((IService) instance).I++));

 

The code for the facility, fluent registration interface,and the tests can be found on our never-ending blog engine, BlogSharp codebase.

, ,

UserVoice for Castle Project

28. April 2009

One of the most active members of Castle Community, Krzysztof Kozmic, has opened a user voice page for Castle, and you can be sure that this page is followed by Castle Committers. We are waiting for your suggestions on any piece of the Castle Stack. In addition, if we reach enough number, Ayende told that he may release Windsor :)

Go ahead and put your voice.

Thank you very much Xtoff!

Castle NHibernate Facility – Configuration

7. April 2009

Castle’s extensibility points provide you many ways to make your life easier. One and most widely used extensibility point is the facilities. By using facilities, you can integrate various other frameworks and technologies easily.

I am going to talk about NHibernate Integration Facility, which is currently lead by me. It was originally written by Hamilton Verissimo, and its current shape is more or less the same as what he wrote.

The purpose of this post is to get feedback and shape the documentation accordingly.

Now, after an historical introduction, lets talk about the facility’s purpose, and in as the first part of the documentation, the configuration.

The purpose
The purpose of this facility to provide an easy way to integrate NHibernate into MicroKernel backed applications. The facility provides a nice way to manage multiple session factories, a good way to manage sessions and it also provides some other structures that can be used to further integrate other frameworks such as Fluent NHibernate. It also plays nicely with other Castle services such as Transaction Management.


The Configuration
Currently, the facility can only be configured via XML, but it provides some extension points that can be used to configure it programmatically. The traditional way of configuring it is as given below. 

<configuration>
    <facilities>
        <facility
          id="nhibernatefacility"
          type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration"
          [optional: configurationBuilder="Your custom configuration builder"] [optional: isWeb="Your custom configuration builder"]>
            <factory id="sessionFactory1">
                <settings>
                    <item key="connection.provider">NHibernate.Connection.DriverConnectionProvider</item>
                    <item key="connection.driver_class">NHibernate.Driver.SqlClientDriver</item>
                    <item key="connection.connection_string">Data Source=.;Initial Catalog=test;Integrated Security=SSPI</item>
                    <item key="dialect">NHibernate.Dialect.MsSql2000Dialect</item>
                    <item key="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</item>
                </settings>
                <assemblies>
                    <assembly>YourAssembly.Name.Here</assembly>
                </assemblies>
            </factory>
        </facility>
    </facilities>
</configuration>
<httpModules>
    <add name="NHibernateSessionWebModule"
             type="Castle.Facilities.NHibernateIntegration.Components.SessionWebModule, Castle.Facilities.NHibernateIntegration"/>
</httpModules>

isWeb: In case of web application, you should set this to true, implement IContainerAccessor in your HttpApplication (the global.asax) also add following lines to your <httpModules> section


As it can bee seen here, it is not very much different from the way we configure NHibernate. What happens behind the scenes are that: Facility creates an NHibernate Configuration, registers the SessionManager, and make those ready to be resolved.

The facility provides you some way to modify the Configuration that is created behind the scenes. The point is called IConfigurationContributor. By implementing classes that derive from that interface and registering them to container, you’ll be able to modify the NHibernate Configuration, just before the SessionFactory is resolved. The interface is simple

public interface IConfigurationContributor
{
    void Process(string name,Configuration config);
}

 

The name corresponds to the id in the configuration.

You can also Configure NHibernate Configuration via the IConfigurationBuilder interface. Currently, there are 2 built in ConfigurationBuilders, namely DefaultConfigurationBuilder and XmlConfigurationBuilder.
The default one is the one that parses the thing you see above while XmlConfigurationBuilder uses NH’s native xmls.

In the next post, I will hopefully show to integrate FluentNHibernate using custom ConfigurationBuilder

, ,

An improvement on SessionFactory Initialization

14. March 2009

UPDATE: I have just committed the PersistentConfigurationBuilder for Castle NHibernate Facility. Thank you Jonathon Rossi for informing me!

We have received several complaints about slowness of SessionFactory initialization when there’s hundreds of entities, and Ayende has replied one of them here. It even gets worse if you’re using it in a web environment. You may think that it is not a problem since SessionFactory is initialized once in a web environment, but the major impact is not on production but development. Think how many times you start your application a day.

The problem is not really with NHibernate but with xml validation against the schema. Here are some profiler results for SessionFactory initialization with one thousand entities:

image

As you see, the adding XML resources takes the most time and the reason behind this is the schema validation. There is also an I/O cost involved (1040 resources should be read by NHibernate). There are several ways to get rid of it, one being the serialization of configuration. I spend 3 days (statics prevented me from spotting some bugs in the code) on this and I believe it pretty much works for every configuration. Another way of doing this is the merging of HBM files, which I believe faster than Serialization as Deserialization also takes some amount.

Now the results for the one using the Deserialized Configuration.

image

A nice feature of dotTrace allows us to compare the performance improvements over the old way.

image

We got 10 seconds rescued! Yay!

Now I am going to show how I used this feature in Castle NHibernate Facility. We have IConfigurationBuilder that is used to integrate various Configuration sources (such as FluentNHibernate).

First of all I must ensure that if any of the files that are used to create the Configuration change, we shouldn’t use the serialized configuration, instead the Configuration should be re-created.

public override Configuration GetConfiguration(IConfiguration config)
{
    log.Debug("Building the Configuration");

    string fileName = config.Attributes["fileName"];

    IConfiguration dependsOn = config.Children["dependsOn"];
    IList<string> list = new List<string>();

    foreach (var on in dependsOn.Children)
        list.Add(on.Value);

    Configuration cfg;
    if (IsNewConfigurationRequired(fileName, list))
    {
        log.Debug("Configuration is either old or some of the dependencies have changed");
        using(var fileStream = new FileStream(fileName, FileMode.OpenOrCreate))
        {
            cfg = base.GetConfiguration(config);
            this.WriteConfigurationToStream(fileStream, cfg);
        }
    }
    else
    {
        using (var fileStream = new FileStream(fileName, FileMode.OpenOrCreate))
        {
            cfg = this.GetConfigurationFromStream(fileStream);
        }
    }
    return cfg;
}protected virtual bool IsNewConfigurationRequired(string fileName,IList<string> dependencies)
{
    if (!File.Exists(fileName))
        return true;
    FileInfo fi = new FileInfo(fileName);
    DateTime lastModified = fi.LastWriteTime;
    bool requiresNew=false;
    for (int i = 0; i < dependencies.Count && !requiresNew; i++)
    {
        FileInfo dependency = new FileInfo(dependencies[i]);
        DateTime dependencyLastModified = dependency.LastWriteTime;
        requiresNew |= dependencyLastModified > lastModified;
    }
    return requiresNew;
}

Code doesn’t look really good, I guess, so I am open to any suggestions on improvement. The code is not yet in Castle Codebase, as our NH dependency on trunk is not the latest (and i am too lazy to update it). When I find time, I may update the dependency if others agree.

There is one thing that you have to be careful about. You must be aware that if you’re using IUserType, IInterceptor, ISqlFunction etc, all of those should be Serializable too!

, ,

NHibernate Integration Facility - IConfigurationContributor

14. February 2009

Note: This short post is a self reminder about a feature that has just been added, I’ll probably use it in the documentation.

Our friend German Schuager has offered another cool feature, namely IConfigurationContributor. This interface allows implementors to change the Configuration instance _just before_ the ISessionFactory is created.

/// <summary>
/// Allows implementors to modify <see cref="Configuration"/>
/// </summary>
public interface IConfigurationContributor
{
    /// <summary>
    /// Modifies available <see cref="Configuration"/> instances.
    /// </summary>
    /// <param name="name">Name of the session factory</param>
    /// <param name="config">The config for sessionFactory</param>
    void Process(string name,Configuration config);
}


Implementors can modify the Configuration depending on the name.

, ,

Castle Custom Component Activators

3. February 2009

I have already said here that  I love Castle and how excited I am  about its extensibility. This post will be another one that talks about Castle Microkernel extensibility.

When you try to resolve a component from microkernel, it goes through several steps. It firsts find the appropriate IHandler instance which manages component states and coordinates component creation/destruction that is associated with the service requested. Handler then calls ILifestyleManager in order to get the object requested. The ILifestyleManager manages the lifestyle of the service, and there are several built-in ILifestyleManagers in Castle.

  1. Singleton(Default)
    Only one instance is created and subsequent calls to Resolve method will get the same instance.
  2. Transient
    Every call gets different instance of the service.
  3. PerWebRequest
    A call creates the instance if it is not created for the current web request. Can only be used in ASP.NET environment
  4. Pooled
    Makes a pool of component instance.
  5. Thread
    A call will create the object if it hasn’t been created for that thread. Otherwise, previously created object will be returned.

 

The ILifestyleManager then calls ComponentActivator in order to create object when necessary.

It has been suggested in Castle Development group that NHibernateIntegrationFacility should lazily initialize ISessionFactory. It is really a good idea and it was something that I had in mind but forgot somehow. German offered that a proxy is registered to container and via this proxy this lazy load could be achieved. This was a good idea but I thought there should be a better way in Castle to handle this kind of situation. Then I remembered something called ComponentActivator and even though I didn’t use it previously, its name gave some idea.

Previously the session factory initialized when the NH facility is initialized,

ISessionFactory sessionFactory = cfg.BuildSessionFactory();
Kernel.AddComponentInstance( id, typeof(ISessionFactory), sessionFactory ); 

Instead of this, I created custom ComponentModel that sets the CustomComponentActivator which will be used to create the object instance

var model = new ComponentModel(id, typeof(ISessionFactory), typeof(Empty));
model.LifestyleType = LifestyleType.Singleton;
model.ExtendedProperties[Constants.SessionFactoryConfiguration] = cfg;
model.CustomComponentActivator = typeof (SessionFactoryActivator);
Kernel.AddCustomComponent( model );

I will have access to that ComponentModel in the activator, and since I provide cfg(Nhibernate.Cfg.Configuration) via ExtendedProperties, I’ll be able to initiate the SessionFactory.

public class SessionFactoryActivator : DefaultComponentActivator
{
    public SessionFactoryActivator(ComponentModel model, IKernel kernel,
        ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction)
        : base(model, kernel, onCreation, onDestruction)
    {

    }
    public override object Create(CreationContext context)
    {
        var configuration = Model.ExtendedProperties[Constants.SessionFactoryConfiguration]
                            as Configuration;
        return configuration.BuildSessionFactory();
    }
}

I really liked this approach that Castle had. I’d like to know if there’s a better of way achieving this specific scenario.

kick it on DotNetKicks.com

, , ,

Castle ServiceIdResolver

19. November 2008

I like Castle, a lot. The thing that I like about it is not only its clean api&design, but also the extensibility points it has.

Sometimes, there are cases when you need to resolve a type that is not registered in the container. Such examples for those cases may be an array of all services of a specific type. An example to this can be found at hammet’s post

This post will be an answer to a question raised in the Castle Project User List.

The question is that he needs his service to be aware of his Id registered in windsor. This is possible with the use of ISubDependencyResolver. Even though this design seems violation of SoC, I believe that it will demonstrate the ISubDependencyResolver well enough.

Tests are first, here they are

public class SampleService1
{
    public SampleService1(string serviceId)
    {
        this.ServiceId = serviceId;
    }
    public string ServiceId { get; set; }
}
public class SampleService2
{
    public SampleService2(string serviceId)
    {
        this.ServiceId = serviceId;
    }
    public string ServiceId { get; set; }
}
public class SampleService3
{
    public SampleService3(int serviceId)
    {
        this.ServiceId = serviceId;
    }
    public int ServiceId { get; set; }
}
public class ServiceIdResolverTests
{
    public ServiceIdResolverTests()
    {
        this.container = new WindsorContainer();
        this.container.Kernel.Resolver.AddSubResolver(new ServiceIdResolver());
        this.container.Register(Component.For<SampleService1>().Named("service1"))
            .Register(Component.For<SampleService2>().Named("service2"))
            .Register(Component.For<SampleService3>().Named("service3"));
    }
    private readonly IWindsorContainer container;

    [Fact]
    public void CanResolveDependencyWithServiceId()
    {
        var s1 = container.Resolve<SampleService1>();
        var s2 = container.Resolve<SampleService2>();
        Assert.Equal("service1", s1.ServiceId);
        Assert.Equal("service2", s2.ServiceId);
        Assert.Throws<HandlerException>(() => container.Resolve<SampleService3>());
    }
}

Now comes to the implementation.

ISubDependencyResolver has 2 simple methods, namely CanResolve and Resolve. CanResolve tells the container that this resolver may handle the operation of resolving and resolve does the real work.

We should define a convention here, about when to resolve a dependency with the service’s id. My convention is if the parameter name is “serviceid”, then this means that the service wants to know about his id.

public class ServiceIdResolver : ISubDependencyResolver
{
    #region ISubDependencyResolver Members
    public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver,
                            ComponentModel model, DependencyModel dependency)
    {
        return dependency.DependencyKey.ToLowerInvariant().Equals("serviceid") &&
               dependency.TargetType == typeof(string);

    }
    public object Resolve(CreationContext context, ISubDependencyResolver parentResolver,
                            ComponentModel model, DependencyModel dependency)
    {
        return model.Name;
    }
    #endregion
}

In CanResolve method, we tell the container that we are able to resolve a dependency only when it is service id, and in the Resolve method we return that dependency to be the service id.

There are still missing points in the code, we should also check if this parameter is defined somewhere in configuration. If that is the case, we shouldn’t resolve it on our own, but leave the container handles this.

Very easy isn’t it?

kick it on DotNetKicks.com

, , ,