views:

419

answers:

1

I'm trying to introduce dependency injection into an existing Web Forms application. The project was created as a Web Site project (as opposed to a Web Application Project). I have seen samples where you create your global class in global.asax.cs 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 web site project, if you ask to add a global class, it adds only 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

}

There doesn't seem to be a way for me to derive from HttpApplication (and IContainerAccessor) here. Or am I missing something obvious?

+2  A: 

I found a way. The global.asax file should only contain:

<%@ Application Language="C#" Inherits="GlobalApp"  %>

then in the 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 _container static. I found that objects of the GlobalApp class were being created multiple times. The Application_Start method is only being called the first time. When I had _container as a non-static field, it was null for the second and subsequent instantiations of the class.

To make referencing the container easy in other portions of the code, I 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;
        }
    }
}

That way, other portions of the code, should they need to access the container can use Ioc.Container.Resolve()

Does this sound like the correct setup?

Decker

related questions