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: