2009-07-22 60 views
13

我正在构建一个应用程序,该应用程序大致遵循存储库模式,顶层有一个服务层,类似于早期版本的Conery MVC店面。服务层应该可以访问HttpContext吗?

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

服务层应该知道HttpContext,从而应用此规则吗?我试图将当前用户(id)从控制器传递给此服务方法,但如果服务层支持HttpContext并且可以独立执行此操作,它似乎更清晰。

一个明显的替代方案是直接在控制器内实施该规则,但我只是不热的这种想法......


编辑 - 只是在回答评论:我看问题与反向依赖问题,我完全忽略了一些东西。我将Mehrdad's评为应得票数,但每个人都提供了值得一读的宝贵回复!

回答

18

绝对不是。我在设计这类事情时的心态是这样的:我假设我需要编写一个基于Windows的应用程序以及Web应用程序,并尽量减少对Web特定内容的依赖。直接传递HttpContext会增加服务层到您的Web UI层的耦合,这是不理想的。

4

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

2

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

+0

简单传递用户标识有什么问题? – 2009-07-22 12:30:38

+0

它根本就没有错,我只是喜欢以同样的方式处理所有情境感知的情况。 – JonoW 2009-07-22 12:33:23

9

答案是,

不仅服务层不应该依赖当前的表示层,我认为它应该不依赖于当前的应用程序。例如,我不会使用定制的AppContext类作为JonoW建议here

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

1

否这样做会使您的代码更难以测试和重用。

我倾向于为这种事情构建一个基础结构接口(称之为IAuthentication或其他),并在其上公开一个CurrentUser属性。然后,我会通过它的构造函数将其注入到我的服务中。即公共MyService(IAuthentication auth)

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

现在,当你创建你的服务,你创建它的依赖,以及:

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

如果您使用的是IoC容器丑陋的依赖性甚至可以走开!

相关问题