如何在Web窗体网站项目中连接Castle Windsor

时间:2009-09-25 03:04:26

标签: castle-windsor ioc-container

我正在尝试将依赖注入引入现有的Web窗体应用程序中。该项目是作为Web站点项目创建的(而不是Web应用程序项目)。我看过你在global.asax.cs中创建全局类的示例,它看起来像这样:

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 = <...>
        }
    }

但是在网站项目中,如果要求添加全局类,它只会添加包含服务器端脚本标记的global.asax:

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

<script runat="server">

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup

}

这里似乎没有办法从HttpApplication(和IContainerAccessor)派生出来。或者我错过了一些明显的东西?

1 个答案:

答案 0 :(得分:5)

我发现了一种方法。 global.asax文件应该只包含:

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

然后在app_code文件夹中创建了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;
        }
    }
}

使_container静态似乎很重要。我发现GlobalApp类的对象被多次创建。 Application_Start方法仅在第一次调用时才会被调用。当我将_container作为非静态字段时,对于该类的第二次和后续实例化,它为null。

为了在代码的其他部分轻松引用容器,我定义了一个帮助器类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;
        }
    }
}

这样,代码的其他部分,如果需要访问容器,可以使用Ioc.Container.Resolve()

这听起来像是正确的设置吗?