IT:AD:Windsor IoC
Summary
A heavy, but well liked IoC.
Process
//application starts...
using (var container = new WindsorContainer())
{
Console.WriteLine(typeof(WindsorContainer).Assembly.FullName);
//Register one by one:
//Choose a lifespan (note that web thread needs registering of a module or fails):
// configuration/system.webServer/modules:
// <add name="PerRequestLifestyle" preCondition="managedHandler" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Microkernel" verb="*" path="*.castle" />
//container.Register(Component.For<ISomeService>().ImplementedBy<SomeService>().LifeStyle.PerWebRequest);
//container.Register(Component.For<ISomeService>().ImplementedBy<SomeService>().LifeStyle.PerThread);
//container.Register(Component.For<ISomeService>().ImplementedBy<SomeService>().LifeStyle.Singleton);
//container.Register(Component.For<ISomeService>().ImplementedBy<SomeService>().LifeStyle.Transient.Named("custom tag"));
//Or non generic way:
//container.Register(Component.For(typeof(ISomeService)).ImplementedBy(typeof(SomeService)).LifeStyle.PerThread);
//or really manual.
ComponentRegistration c1 = Component.For(typeof(ISomeService));
ComponentRegistration<object> c2 = c1.ImplementedBy(typeof(SomeService));
//Kick in:
var o = c2.LifeStyle.PerThread;
container.Register(o);
// adds and configures all components using WindsorInstallers from executing assembly
//container.Install(FromAssembly.This());
// instantiate and configure root component and all its dependencies and their dependencies and...
var svc = container.Resolve<ISomeService>();
var result = svc.DoSomething();
// clean up, application exits
}
public interface ISomeService
{
string DoSomething();
}
public class SomeService: ISomeService
{
public string DoSomething() { return "Hi"; }
}
To use reflection:
public static void RegisterServiceInUnityByReflection(object ioc, Type interfaceType, Type instanceType, BindingLifetimeType serviceLifetimeType, string tag = null)
{
string assemblyName = "Castle.Windsor, Version=3.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc";
//Invoke static method:
string componentName = string.Concat("Castle.MicroKernel.Registration.Component", ",", assemblyName);
Type componentType = Type.GetType(componentName);
//Define Interface:
var interfaceComponentRegistration = componentType.InvokeMember(
"For",
BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod,
null,
null,
new object[] {interfaceType});
//Define Implementation:
object implemenationComponentRegistration =
interfaceComponentRegistration
.InvokeMethod("ImplementedBy",
new[] {typeof (Type)},
new[] {instanceType});
//Define Lifespan:
object lifeStyleGroup = implemenationComponentRegistration.GetValue("LifeStyle");
object lifeStyle = null;
switch (serviceLifetimeType)
{
case BindingLifetimeType.SingletonPerWebRequestScope:
if (ApplicationEnvironment.HttpContext!=null)
{
lifeStyle = lifeStyleGroup.GetValue("PerWebRequest");
}
else
{
lifeStyle = lifeStyleGroup.GetValue("PerThread");
}
break;
case BindingLifetimeType.SingletonPerThreadScope:
lifeStyle = lifeStyleGroup.GetValue("PerThread");
break;
case BindingLifetimeType.SingletonScope:
lifeStyle = lifeStyleGroup.GetValue("Singleton");
break;
case BindingLifetimeType.TransientScope:
lifeStyle = lifeStyleGroup.GetValue("Transient");
break;
default:
throw new ArgumentOutOfRangeException("serviceLifetimeType");
}
//Name it if need be:
object registerMe = lifeStyle;
if (!string.IsNullOrEmpty(tag))
{
registerMe = registerMe.InvokeMethod("Named", new object[] { tag });
}
//Create an array from the same type:
Array arrayWithSize1 = Array.CreateInstance(lifeStyle.GetType(), 1);
//and fill it with our one entry:
arrayWithSize1.SetValue(registerMe, 0);
//Pass it to the IoC:
ioc.InvokeMethod("Register", new object[] {arrayWithSize1});
}
Issues
- Web Thread LifeStyle config mistake: