mvc将httpcontext注入服务层



在使用unity将httpContextBase注入到控制器中的服务级别对象时,我遇到了一个大问题。

样品控制器

public HomeController : Controller{
    private IWorkContext _context;
    public HomeController(IWorkContext context){
        _context = context;
    }
}

public WorkContext : IWorkContext{
    private HttpContextBase _httpContext;
        public (HttpContextBase httpContext){
            _httpContext = httpContext;
        }
        public void DealWithCookies(){
            //do some thing with http context and deal with cookies
        }
    }

内部统一引导程序

container.RegisterType<HttpContextBase>().RegisterInstance(new HttpContextWrapper(HttpContext.Current) as HttpContextBase, new ContainerControlledLifetimeManager());
//With this line httpcontextbase is returned but as a singleton instead of new for each request.

   container.RegisterType<HttpContextBase>().RegisterInstance(new HttpContextWrapper(HttpContext.Current) as HttpContextBase, new PerRequestLifetimeManager());
//This line returns an exception 

类型HttpContextBase没有可访问的构造函数。

我根本不会注入HttpContext——我会将其传递到每个方法调用中:

public WorkContext : IWorkContext{
    private HttpContextBase _httpContext;
    public WorkContext(){
        ...
    }
    public void DealWithCookies(HttpContext ctx){
        //do some thing with http context and deal with cookies
    }
}

在我看来,试图在这里使用依赖注入似乎是对原则的挪用。依赖注入允许您松散地耦合组件,但在这里没有必要这样做,因为您可以将上下文传递到方法中并直接操作它。没有接口可以提供的具体实现,所以DI没有任何好处——这只是不必要的自举和缺乏结构的"反模式"。

更不用说,考虑到在应用程序启动时注册类型时,没有要注册的实例(并且实例需要在每次请求时更改),您无论如何都无法做到这一点。

顺便说一句,我希望IWorkContext只是用于抽象cookie逻辑,而不是位于应用程序和数据层之间的一层。如果没有,它就不应该依赖于HTTP上下文。

FYI您可以按照这篇关于TDD和MVC的文章将http上下文模拟到控制器中:

http://msdn.microsoft.com/en-us/library/ff847525(v=vs.100).aspx

如果不能注入HttpContextBase实现的实例,请执行以下操作(在我的项目中有效!!):

container.RegisterType(new InjectionFactory(c=>new HttpContextWrapper(HttpContext.Current));

最新更新