ASP.NET MVC和Windsor.Castle:使用依赖于HttpContext的服务

Igo*_*ejc 12 asp.net-mvc castle-windsor inversion-of-control

我有几个依赖注入服务,它依赖于HTTP上下文之类的东西.现在我将它们配置为Application_Start处理程序中的Windsor容器的单例,这显然是此类服务的问题.

处理这个问题的最佳方法是什么?我正在考虑将它们设置为瞬态,然后在每次HTTP请求后释放它们.但是将HTTP上下文注入其中的最佳方式/地点是什么?控制器工厂或其他地方?

Mau*_*fer 24

就像Mark说的那样,你需要将这些依赖于http的服务注册为PerWebRequest或Transient.这是一个示例,说明如何注册和注入HttpRequest或HttpContext:

public class Service {
    private readonly HttpRequestBase request;

    public Service(HttpRequestBase request) {
        this.request = request;
    }

    public string RawUrl {
        get {
            return request.RawUrl;
        }
    }
}

...

protected void Application_Start(object sender, EventArgs e) {
    IWindsorContainer container = new WindsorContainer();
    container.AddFacility<FactorySupportFacility>();
    container.AddComponentLifeStyle<Service>(LifestyleType.Transient);

  container.Register(Component.For<HttpRequestBase>()
      .LifeStyle.PerWebRequest
      .UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request)));

  container.Register(Component.For<HttpContextBase>()
      .LifeStyle.PerWebRequest
      .UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));  
}
Run Code Online (Sandbox Code Playgroud)

通过使用HttpRequestBase而不是HttpRequest你可以轻松地模拟出来进行测试.另外,不要忘记PerWebRequestLifestyleModule在web.config中注册.


Mar*_*ann 5

使用Castle Windsor,你可以使用它的PerWebRequest寿命 - 这应该与你的要求非常吻合.

这意味着您可以将HTTP内容注入您的服务,容器将负责适当的生命周期管理.但是,这要求您还将所有这些服务(以及这些服务的所有使用者等)注册为PerWebRequest(或Transient),因为如果将它们注册为Singletons,它们将保持陈旧(并可能处置)的上下文.