mickdelaney
6/25/2014 - 3:54 PM

Applying a lifestyle to a collection of Windsor component registrations

Applying a lifestyle to a collection of Windsor component registrations

using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ModelBuilder.Descriptors;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

interface IServiceA { }

class ServiceA : IServiceA { }

interface IServiceB { }

class ServiceB : IServiceB { }

public interface IHRegistration: IRegistration {
    void ApplyLifestyle(LifestyleType t);
}

public class HComponentRegistration<T> : IHRegistration where T: class {
    public readonly ComponentRegistration<T> registration;

    public HComponentRegistration(ComponentRegistration<T> registration) {
        this.registration = registration;
    }

    public void ApplyLifestyle(LifestyleType t) {
        registration.AddDescriptor(new LifestyleDescriptor<T>(t));
    }

    public void Register(IKernelInternal kernel) {
        ((IRegistration) registration).Register(kernel);
    }
}

public static class HReg {
    public static IHRegistration AsHReg<T>(this ComponentRegistration<T> r) where T : class {
        return new HComponentRegistration<T>(r);
    }
}

class MyInstaller: IWindsorInstaller {
    private readonly LifestyleType lifestyle;

    public MyInstaller(LifestyleType lifestyle) {
        this.lifestyle = lifestyle;
    }

    public void Install(IWindsorContainer container, IConfigurationStore store) {
        var registrations = new[] { 
            Component.For<IServiceA>().ImplementedBy<ServiceA>().AsHReg(), 
            Component.For<IServiceB>().ImplementedBy<ServiceB>().AsHReg() 
        }
            .Select(x => { 
                x.ApplyLifestyle(lifestyle); 
                return x; 
            });
        container.Register(registrations.ToArray());
    }
}

class Program {
    static void Main(string[] args) {
        using (var container = new WindsorContainer()) {
            container.Install(new MyInstaller(LifestyleType.Transient));
            var a1 = container.Resolve<IServiceA>();
            var a2 = container.Resolve<IServiceA>();
            if (a1 == a2)
                throw new Exception("Not transient!");
        }

        using (var container = new WindsorContainer()) {
            container.Install(new MyInstaller(LifestyleType.Singleton));
            var a1 = container.Resolve<IServiceA>();
            var a2 = container.Resolve<IServiceA>();
            if (a1 != a2)
                throw new Exception("Not singleton!");
        }
    }
}