使用Castle Windsor在遗留代码中注入HttpContext.Current.Session

Tom*_*han 2 session dependency-injection castle-windsor asp.net-mvc-2

tl; dr:
在遗留应用程序中,文化信息存储在HttpContext.Current.Session["culture"].我如何在这里介绍DI与温莎,所以当运行应用程序仍然获取并设置文化信息,但我可以在我的测试中模拟它?

完整背景:
我有一些遗留代码用于本地化,我希望重构以实现模拟和测试.目前,自定义类Lang基于提供string key和打开来获取本地化字符串HttpContext.Current.Session["culture"] as CultureInfo.

我最初的想法是简单地CultureInfo使用Windsor 注入一个实例,然后安装它以便在运行整个Web应用程序时从同一个地方获取它,但是在测试时我只需注册一个new CultureInfo("en-GB").这是我为安装程序提出的:

public class CultureInfoFromSessionInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register( // exception here (see comments below)
            Component.For<CultureInfo>()
            .Instance(HttpContext.Current.Session["culture"] as CultureInfo)
            .LifeStyle.PerWebSession());
    }
}
class EnglishCultureInfoInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<CultureInfo>()
            .Instance(new CultureInfo("en-GB")));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是现在运行应用程序时,我在指定的行上得到一个空引用异常.我怀疑这是因为我试图过早地挂起它 - 容器已初始化并且安装程序Application_Start在Global.asax.cs中注册,我不确定HttpContext.Current.Session(或者甚至HttpContext.Current)是否已设置.

有没有一个很好的方法来获得我在这里想要做的事情?

Mau*_*fer 5

延迟组件的实例化:

container.Register( 
        Component.For<CultureInfo>()
        .UsingFactoryMethod(() => HttpContext.Current.Session["culture"] as CultureInfo)
        .LifeStyle.PerWebSession());
Run Code Online (Sandbox Code Playgroud)