从服务访问 HttpContext 的正确方法



我创建了一个服务,允许我从HttpContext.Current 访问控制器名称,actionname和标头值

它目前正在工作,但是我正在尝试测试服务并发现在服务中使用HttpContext可能是一个坏主意,因为我的服务层需要完全了解HttpContext。

例如

    public virtual string GetControllerName()
    {
        return HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
    }

然后我想到将请求作为参数传递,但这又感觉不对。

   public virtual string GetActionName(HttpRequest request)
   {
      return request.RequestContext.RouteData.Values["action"].ToString();
   }

任何人都可以提供有关如何设置我的服务以允许我实现所需内容的指导吗?

如果您的服务类"知道"存在控制器和操作,则它知道在向控制器发出 HTTP 请求期间正在调用它。如果是这种情况,那么它不会与控制器分离 - 换句话说,如果在为请求提供服务时未调用该服务,则该服务将无法运行。因为如果是这样,就不可能有控制器或动作。

因此,从这个角度来看,服务直接依赖于HttpContext并不重要,因为它以任何一种方式耦合到它。

服务类是否真的需要这些特定值,或者它只是执行一些日志记录,而你想知道是什么叫了它?

如果它取决于这些值,那么您可以创建一个接口,例如

interface IControllerContextProvider
{
    string ControllerName;
    string ActionName;
}

然后有一个实现,比如

public class HttpContextControllerContextProvider : IControllerContextProvider
{
    //implements the interface by returning values from HttpContext.Current
}

如果服务本身不需要这些值来运行(也许它只是日志记录(,那么您可以使用拦截器(参见PostSharp,Windsor等(,当您将服务注入控制器时,拦截器会"拦截"调用,执行日志记录,然后继续原始方法调用。

拦截器是为该特定目的编写的类,因此将其耦合到您的HttpContext是有意义的。但好处是,如果有关控制器和操作的详细信息与服务类的主要用途并不真正相关,则拦截器提供了一种将该代码排除在服务类之外的方法。

异常日志记录做了很多工作。如果一个类实际上不会处理异常,那么它就不需要包含代码来记录错误,因为这不是该类的目的。拦截器允许我们创建这些行为,但将它们与不关心它们的类分开。

相关内容

最新更新