开发者

Injecting HttpContext.Current.Session in legacy code using Castle Windsor

开发者 https://www.devze.com 2023-03-20 19:11 出处:网络
tl;dr: In a legacy app, culture info is stored in HttpContext.Current.Session[\"culture\"]. How do I introduce DI with Windsor here, so that when running the application still gets and sets culture in

tl;dr:

In a legacy app, culture info is stored in HttpContext.Current.Session["culture"]. How do I introduce DI with Windsor here, so that when running the application still gets and sets culture info there, but I can mock it in my tests?

Full background:

I have some legacy code for locali开发者_运维技巧zation, that I wish to refactor to enable mocking and testing. Currently, a custom class Lang fetches localized strings based on a provided string key and on HttpContext.Current.Session["culture"] as CultureInfo.

My initial idea was to simply inject a CultureInfo instance using Windsor, and install it to get it from the same place as before when running the entire web application, but when testing I'd simply register a new CultureInfo("en-GB") instead. This is what I came up with for the installers:

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")));
    }
}

But now when running the application I get a null reference exception on the indicated line. I suspect this is because I'm trying to hook this up too early - the container is initialized and the installer registered under Application_Start in Global.asax.cs, and I'm not sure HttpContext.Current.Session (or even HttpContext.Current) is set by then.

Is there a nice way to obtain what I'm trying to do here?


Delay the instantiation of the component:

container.Register( 
        Component.For<CultureInfo>()
        .UsingFactoryMethod(() => HttpContext.Current.Session["culture"] as CultureInfo)
        .LifeStyle.PerWebSession());
0

精彩评论

暂无评论...
验证码 换一张
取 消