How to connect Castle Windsor to a Web Site Project website
I am trying to inject dependency injection into an existing Web Forms application. The project was created as a website project (as opposed to a web application project). I've seen examples where you create your global class in the global.asax.cs file and it looks something like this:
public class GlobalApplication : HttpApplication, IContainerAccessor
{
private static IWindsorContainer container;
public IWindsorContainer Container
{
get { return container; }
}
protected void Application_Start(object sender, EventArgs e)
{
if (container == null)
{
container = <...>
}
}
But in a website project, if you ask to add a global class, it only adds global.asax which contains a server side script tag:
<%@ Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
}
It seems to me that there is no way to get from HttpApplication (and IContainerAccessor) here. Or am I missing something obvious?
source to share
I found a way. The global.asax file should only contain:
<%@ Application Language="C#" Inherits="GlobalApp" %>
then in app_code folder i created GlobalApp.cs
using System;
using System.Web;
using Castle.Windsor;
public class GlobalApp : HttpApplication, IContainerAccessor
{
private static IWindsorContainer _container;
private static IWindsorContainer Container {
get
{
if (_container == null)
throw new Exception("The container is the global application object is NULL?");
return _container;
}
}
protected void Application_Start(object sender, EventArgs e) {
if (_container == null) {
_container = LitPortal.Ioc.ContainerBuilder.Build();
}
}
IWindsorContainer IContainerAccessor.Container
{
get {
return Container;
}
}
}
It seems important to make it static _container
. I found that objects of the GlobalApp class are created multiple times. The Application_Start method is only called the first time. When I had _container
as a non-static field it was null for the second and subsequent instances of the class.
To make it easier to refer to the container in other parts of the code, I have defined a helper class Ioc.cs
using System.Web;
using Castle.Windsor;
public static class Ioc
{
public static IWindsorContainer Container {
get {
IContainerAccessor containerAccessor = HttpContext.Current.ApplicationInstance as IContainerAccessor;
return containerAccessor.Container;
}
}
}
Thus, other parts of the code, if they need to access the container, can use Ioc.Container.Resolve()
Does this sound like the correct setting?
source to share