我需要通过在Web API服务中的所有数据库调用上请求主机名来应用过滤。
此过滤的工作原理如下:
本质上是一个全局过滤器,以便API服务返回的数据始终包含在主机中。
一种解决方案是将主机名作为参数传递给我所有的服务方法,如:
public IEnumerable<Profiles> GetProfiles ()
{
var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
return profilesService.Get(host);
}
但由于这是对所有请求的一致规则,我想提出一种更优雅的方式来处理这个问题,所以我的服务调用只是profileSerivce.Get();
我认为我需要将ISiteLocator注入我的服务层,该服务层具有主机名,甚至更好的已经从数据库中检索到的Id然后我可以应用。但是我正在努力解决HttpContext如何以及在哪里获取主机名,以及是否可以使用StructureMap生命周期来优化它。
答案 0 :(得分:2)
我想我需要将ISiteLocator注入我的服务层
在我看来,你正朝着正确的方向前进。
我正在努力研究如何以及在哪里引用它 HttpContext的
实际上这很简单。在您的业务层中定义ISiteLocator
并在ASP.NET Web应用程序中定义AspNetSiteLocator
实现,最好在您的Composition Root附近(或内部)。该实现可能如下所示:
public class AspNetSiteLocator : ISiteLocator
{
private readonly ISiteRepository siteRepository;
public AspNetSiteLocator(ISiteRepository siteRepository)
{
this.siteRepository = siteRepository;
}
Site ISiteLocator.GetCurrentSite()
{
return this.siteRepository.GetById(CurrentHostName);
}
private static string CurrentHostName
{
get
{
return HttpContext.Current.Request
.ServerVariables["SERVER_NAME"];
}
}
}
具有主机名或甚至更好的Id已检索 来自数据库
尝试让ISiteLocator
以对该定位器的使用者最方便的方式返回数据。在我的示例中,我返回了一个Site
实体(如果您的域中有这样的实体)。这可能比主机名或Id更方便,因为消费者可能不得不再次查询该站点。但是,也许Id是最方便的,但这取决于你找出来。
如何使用StructureMap生命周期来优化它
上面的实现没有任何状态,因此可以在任何生命周期内注册;例如单身人士。但是,每次调用ISiteLocator.GetCurrentSite()
都会向ISiteRepository
发出新请求,这可能会导致过多的开销。在这种情况下,您可能需要一个将Site
存储在私有字段中的实现,并始终返回该实例。在这种情况下,您应该在“每Web请求”的基础上注册该实现(因为SERVER_NAME
在请求期间不会更改。)