I need to apply filtering by requesting host name on all database calls in my Web API service.
This filtering works like so:
- lookup the Site to profile against based on the requesting hostname
- Apply Site.Id on all subsequent data access calls made in the request
Essentially a global filter so so that data returned by the API service is always contained to the host.
One solution would be to pass the host name in as an argument on all my service methods like so:
public IEnumerable<Profiles> GetProfiles ()
{
var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
return profilesService.Get(host);
}
But since this is a consistent rule on all requests I would like to come up with a more elegant way to handle this so my service calls are just profileSerivce.Get();
I think I need to inject a ISiteLocator into my service layer that has either the host name or even better the Id already retrieved from the database that I can then apply. But I’m struggling with this on how and where I can reference the HttpContext to get the host name and also if it was possible to optimise this using StructureMap lifecycles.
It seems to me you are heading into the right direction.
This is really simple actually. Define the
ISiteLocatorin your business layer and define anAspNetSiteLocatorimplementation into your ASP.NET web application, preferably close to (or inside) your Composition Root. That implementation might look like this:Try to let your
ISiteLocatorreturn data in a way that is most convenient to the consumers of that locator. In my example I returned aSiteentity (if you have such an entity in your domain). This is probably more convenient than the host name or the Id, since consumers possibly have to query for the site again thereselves. However, perhaps Id is the most convenient, but that’s up to you to find out.The implementation above doesn’t have any state, so it can be registered with any lifetime; singleton for instance. However, every call to
ISiteLocator.GetCurrentSite()will result in a new request to theISiteRepository, which can cause too much overhead. In that case you probably want an implementation that stores theSitein a private field and always returns that instance. In that case you shoud register that implementation on a ‘Per Web Request’ basis (since theSERVER_NAMEwill not change during the request).