代码之家  ›  专栏  ›  技术社区  ›  Elijah66

服务层是否应该访问httpcontext?

  •  13
  • Elijah66  · 技术社区  · 15 年前

    我正在构建一个大致遵循存储库模式的应用程序,上面有一个服务层,类似于Conery的MVC店面的早期版本。

    我需要实现一个返回除当前用户以外的所有用户的页面。我已经在存储库和服务层上使用了getUsers()方法,所以问题是在哪里应用“除了当前用户”。

    服务层是否应该知道httpcontext,从而应用此规则?我很想将当前用户(ID)从控制器传递给这个服务方法,但是如果服务层了解HTTPContext并且可以自己这样做,那么它看起来就更干净了。

    一个明显的选择是直接在控制器中应用这个规则,但是我并不热衷于这个想法…


    编辑-只是对答案发表评论:我看到了反向依赖性问题,这是我完全忽略的问题。我将Mehrdad的答案标记为得票,但每个人都提供了值得一读的有价值的回答!

    5 回复  |  直到 15 年前
        1
  •  18
  •   Mehrdad Afshari    15 年前

    绝对不是。我在设计这些东西时的心态是这样的:我假设我需要编写一个基于Windows的应用程序和Web应用程序,并尽量减少对特定于Web的东西的依赖。经过 HttpContext 直接增加服务层与Web UI层的耦合,这是不理想的。

        2
  •  9
  •   Community CDub    7 年前

    答案是, .

    服务层不仅不应该依赖于当前的表示层,在我看来,它也不应该依赖于当前的应用程序。例如,我不会使用自定义 AppContext 类AS JonoW 建议 here .

    相反,将当前用户作为参数传递给 GetAllUsersExceptForTheCurrentUser 方法。这样,服务就可以被任何需要处理用户的应用程序使用,而不仅仅是当前应用程序。

        3
  •  4
  •   tvanfosson    15 年前

    你应该 在服务层和Web层之间创建反向依赖关系。考虑当您希望扩展服务层以使用基于窗体的应用程序或Windows服务时会发生什么。现在,您必须解决Web依赖关系,以使相同的方法工作或复制一些(可能很小,但仍然是重复的)代码。您最好将用户的标识符提取到服务层上下文中有用的内容中,并将该值与服务层一起使用。在网站上处理过滤也是可以接受的,但是如果你做了不止一次,它将需要重构到一个公共的地方,并且服务层是它的自然位置。

        4
  •  2
  •   JonoW    15 年前

    我发现构建包含当前用户对象(以及其他上下文数据)的自定义AppContext类是一个很好的实践。此类没有对System.Web的引用。任何需要上下文感知的服务方法都应该有一个appcontext参数(例如,用于检查安全权限,或者像在您的情况下那样获取当前用户)。在Web层中填充此对象,并在需要时将其保留在会话中。这样,您的服务层对System.Web一无所知。

        5
  •  1
  •   Mike Minutillo    15 年前

    不,这样做会使代码更难测试和重用。

    我倾向于为这类东西构建一个基础结构接口(称之为IAuthentication或其他东西),并在上面公开一个currentUser属性。然后我将通过它的一个构造函数将它注入到我的服务中。即公共myservice(iaauthentication auth)

    最后,您可以构建一个支持HTTPContext的IAuthentication实现(比如WebAuthentication)。

    现在,当您创建服务时,也会创建其依赖项:

    var myService = new MyService(new WebAuthentication());
    var otherUsers = myService.GetAllOtherUsers();
    

    如果您使用的是IOC容器,那么丑陋的依赖关系甚至可以消失!