I am a Castle Winsor Noob. I have a WebForm project that is a hot mess. I am trying to resolve a dependency to test user registration. How do I get to the current WindsorContainer?
IWindsorContainer container = ???;
IRegistrationLogic registrationLogic = container.Resolve<IRegistrationLogic>();
_registrationLogic.Register();
Here is my Bootstrapper:
public class WindsorConfigTask : ICastleBootstrapperTask
{
public void Execute()
{
Container.AddFacility<WcfFacility>();
Container.Register(
Component.For<IProcessMessageRequest>()
.ActAs(
new DefaultClientModel
{
Endpoint =
WcfEndpoint.ForContract<IProcessMessageRequest>().FromConfiguration("surveyClient2")
}
),
Component.For<ILocalMembershipService>()
.ActAs(
new DefaultClientModel
{
Endpoint =
WcfEndpoint.ForContract<ILocalMembershipService>().FromConfiguration(
"localMembershipClient")
})
);
Container.Register(Component.For<IRegistrationLogic>()
.ImplementedBy<RegistrationLogic>()
.LifeStyle.Is(LifeStyleType));
}
public IWindsorContainer Container { get; set; }
#region ICastleBootstrapperTask Members
public Castle.Core.LifestyleType LifeStyleType
{
get;
set;
}
#endregion
}
There is interface in Windsor for this purpose. It is called IContainerAccessor. Best place to implement it is the Global.asax
file:
public class WebApplication : HttpApplication, IContainerAccessor {
static IWindsorContainer container;
public IWindsorContainer Container {
get { return container; }
}
protected void Application_Start() {
var bootstrapper = new WindsorConfigTask();
bootstrapper.Execute();
container = bootstrapper.Container;
}
protected void Application_End() {
container.Dispose();
}
}
The usage in your web form is as following:
var containerAccessor = Context.ApplicationInstance as IContainerAccessor;
var container = containerAccessor.Container;
There are many ways to solve this problem but I think the most common is to create a singleton helper class to hold the reference. Keep in mind you want to app to use DI to get everything from the container automatically. Perhaps only a few calls from the app will be to the container. Look at the controller factories for Windsor.
Something like this...
public static class ContainerManager
{
public static IWindsorContainer Container = null;
}
Now I have been known to take it a step further and you could include some utilities with a get...
public static class ContainerManager
{
private static IWindsorContainer _container = null;
public static IWindsorContainer Container
{
get {
if (_container == null) {
// run installers, set _container = new container
}
return _container;
}
}
}
I also realize you might be asking how do I get the container from a downstream dependent object... you can register the container with its self. By default it will register IKernel, but you can register IWindsorContainer for injection later. I would highly discourage using the container directly. As in you code above... do you do a Release when you are done???
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With