在服务层中使用HttpContextBase

时间:2012-08-21 07:19:43

标签: asp.net-mvc unit-testing dependency-injection unity-container service-layer

我最近开始使用TDD和依赖注入。这是一个大的心态变化,我仍然试图拼凑所有的部分。

我有一个服务层用于所有业务逻辑,以使控制器尽可能地保持薄。我的服务中的一些服务需要HttpContext。什么是创建服务的最佳方式,以便也可以进行单元测试。

目前我有一个看起来像这样的ServiceBase

public class HttpContextService 
{
    private HttpContextBase _ServiceContext;
    public HttpContextBase ServiceContext 
    { 
        get
        {
            if (_ServiceContext == null)
                _ServiceContext = new HttpContextWrapper(HttpContext.Current);
            return _ServiceContext;
        }  
        set { _ServiceContext = value; }  
    }
}

所以这意味着我的所有服务都可以继承这项服务。我为HttpContextBase创建属性的原因是我可以在单元测试服务时设置它。 1.有没有办法在Unity Bootstrap文件中将HttpContext注入服务。 ? 这是正确的做法还是我错过了什么?

提前谢谢。就像我说的那样,我很想知道整个TDD依赖注入编码方式。

1 个答案:

答案 0 :(得分:2)

  

我服务中的某些服务需要HttpContext

您的服务应该存在于业务层中,而该层应该没有您使用的表示技术的概念。这允许您将此逻辑重用于不同的技术(例如WCF Web服务或Windows服务)。但即使您不打算重用此代码,将服务与HttpContextBase紧密耦合仍然会增加复杂性,并使单元测试变得更加困难,正如您已经遇到的那样。

解决方案是从后面的HttpContextBase抽象中抽象出你想要的东西,而不是对完整HttpContext的抽象,而是在某个特定情况下要使用的各个功能。

例如,当您想要访问HttpContextBase.User属性时,您会更好地使用以下抽象:

public interface IUserContext
{
    IIdentity Current { get; }
}

这使得测试更容易,您的服务更简单,并且可以更简单地为不同的应用程序创建不同的实现。