Reputation: 9963
I have created a service that allows me access a controllername,actionname & header values from HttpContext.Current
Its working currently however I am trying to test the service and discovering using HttpContext within the service might be a bad idea as my service layer needs to be fully aware of HttpContext
e.g.
public virtual string GetControllerName()
{
return HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
}
I then thought of passing the request through as a paramater but again this doesnt feel right.
public virtual string GetActionName(HttpRequest request)
{
return request.RequestContext.RouteData.Values["action"].ToString();
}
Can anyone provide and guidance on how my service should be setup to allow me to achieve what I need?
Upvotes: 0
Views: 1148
Reputation: 29222
If your service class is "aware" that there is a controller and an action, then it knows it's being called during an HTTP request to a controller. If that's the case then it's not decoupled from the controller - in other words, that service can't function if it's not called while servicing a request. Because if it was, there couldn't be a controller or an action.
So from that point of view, it doesn't matter too much that the service is depending directly on the HttpContext
, because it's coupled to it either way.
Does the service class actually need those specific values, or is it just performing some logging and you want to know what called it?
If it depends on those values then you could create an interface like
interface IControllerContextProvider
{
string ControllerName;
string ActionName;
}
Then have an implementation like
public class HttpContextControllerContextProvider : IControllerContextProvider
{
//implements the interface by returning values from HttpContext.Current
}
If the service itself doesn't need those values in order to function (maybe it's just logging) then you could use an interceptor (see PostSharp, Windsor, others) and when you inject your service into your controller, the interceptor "intercepts" the call, does your logging, and then continues with the original method call.
The interceptor is a class written for that specific purpose, so it makes sense for it to be coupled to your HttpContext
. But the benefit is that if the details about the controller and action aren't really relevant to the main purpose of your service class then the interceptor provides a way to keep that code out of your service class.
That's done a lot with exception logging. If a class isn't going to actually handle exceptions then there's no need for it to contain code to log errors, since that's not the purpose of that class. Interceptors let us create those behaviors but keep them separate from classes that don't care about them.
Upvotes: 1