2

既存の 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 = <...>
        }
    }

しかし、Web サイト プロジェクトでグローバル クラスの追加を要求すると、サーバー側のスクリプト タグを含む global.asax のみが追加されます。

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

<script runat="server">

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

}

ここで HttpApplication (および IContainerAccessor) から派生させる方法はないようです。それとも、明らかな何かが欠けていますか?

4

1 に答える 1

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非静的フィールドとして持っていた場合、クラスの 2 回目以降のインスタンス化では 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()

これは正しいセットアップのように聞こえますか?

于 2009-09-25T07:05:59.823 に答える