ASP.NET MVC:HTTPContext和依赖注入如何实现?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (22)

目前我有一个ActionFilter,它从HttpContext获取当前用户名,并将它传递给在服务方法上使用它的动作。例如:

Service.DoSomething(userName);

我现在有一个理由,不是在操作级别,而是在控制器构造器级别。目前我正在使用结构图来创建控制器并注入服务。我正在看像这样的东西:

public interface IUserProvider
{
    string UserName { get; }
}

public class HttpContextUserProvider : IUserProvider
{
    private HttpContext context;

    public HttpContextUserProvider(HttpContext context)
    {
        this.context = context;
    }

    public string UserName
    {
        get
        {
            return context.User.Identity.Name;
        }
    }
}

这就是说,我的IoC foo真的很脆弱,因为这是我使用过的第一个项目。

所以我的问题是...我怎么能告诉结构图在HttpContextUserProvider的构造函数中传入HttpContext?这似乎很奇怪......我不知道如何考虑HttpContext。

提问于
用户回答回答于

有一个接口抽象HttpContext.Current。只公开你需要的方法。GetUserName()例如,在实现中会调用HttpContext.Current.User.Identity.Name。尽可能薄。

采取这种抽象并将其注入到其他提供者类中。这将允许您通过模拟http上下文抽象来测试提供者。作为一个好处,除了嘲笑它之外,你可以用HttpContext抽象来做其他漂亮的事情。重新使用它,一件事。向包包等添加泛型类型参数

用户回答回答于

这听起来像你应该使用,HttpContextBase而不是HttpContextUserProvider。这是一个开箱即用的抽象,HttpContext并允许创建一个模拟,写入UnitTests并注入依赖关系。

public class SomethingWithDependenciesOnContext
{
    public SomethingWithDependenciesOnContext(HttpContextBase context) {
        ...
    }

    public string UserName
    {
        get {return context.User.Identity.Name;}
    }
}

ObjectFactory.Initialize(x => 
          x.For<HttpContextBase>()
          .HybridHttpOrThreadLocalScoped()
          .Use(() => new HttpContextWrapper(HttpContext.Current));

扫码关注云+社区