I am a little confused over which layers my filters should be contained in with an n-layer web application.
I've got 4 layers:
- Presentation layer
- Application layer
- Business layer
- Infrastructure layer
The Presentation layer can only talk to the Application layer and the Infrastructure layer. The Application layer can only talk to the Presentation layer, Business layer and the Infrastructure layer. The Business layer can only talk to the Application layer and the Infrastructure layer.
All my models, views and controllers are stored in the Presentation layer.
I have the following code:
public class AuthoriseAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (SkipAuthorisation(filterContext))
{
return;
}
// This line...
var evalReportProxy = new EvalReportProxy(WebHelper.PcwAliasName);
if (evalReportProxy.EvalReport.SubscribedToModule("Workspace Only"))
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Redirect" },
{ "action", "Workspace" }
});
}
if (string.IsNullOrEmpty(WebHelper.Username) || WebHelper.IsGuest)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Account" },
{ "action", "LogIn" }
});
}
}
private static bool SkipAuthorisation(AuthorizationContext filterContext)
{
return filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true);
}
}
I've highlighted a line of code using a comment which shows where I am making use of a concrete type in the infrastructure layer to check to see if a user is subscribed to a module. By using a concrete type I've made it impossible to use mock objects which I want to avoid, but...
I'm a little confused because in the line highlighted using a comment I guess I should really be using a repository or a service although I'm not really sure if I should be or not. Also, if I use a repository then the filters can't be in the presentation layer, but I'm not sure if services are purely for controllers or whether I can use services elsewhere.
Can anyone please advise me on whether I should be putting filters in the presentation layer or not, and whether or not I should be using a service, repository, or keep the code how it is.
Also, I'm open to code improvements if you think any can be made.