正在将主机从HttpContext注入服务层



我需要通过请求Web API服务中所有数据库调用的主机名来应用筛选。

这种过滤是这样工作的:

  1. 根据请求的主机名查找要配置文件的站点
  2. 在请求中进行的所有后续数据访问调用上应用Site.Id

本质上是一个全局过滤器,因此API服务返回的数据始终包含在主机中。

一个解决方案是将主机名作为参数传入我的所有服务方法,如下所示:

public IEnumerable<Profiles> GetProfiles ()
{
var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
return profilesService.Get(host);
}

但由于这是所有请求的一致规则,我想想出一种更优雅的方法来处理它,所以我的服务调用只是profileSerivce.Get();

我想我需要在我的服务层中注入一个ISiteLocator,它要么有主机名,要么更好的是已经从数据库中检索到的Id,然后我可以应用它。但我很难理解如何以及在哪里引用HttpContext来获得主机名,以及是否可以使用StructureMap生命周期来优化它。

我想我需要在我的服务层中注入一个ISiteLocator

在我看来,你正朝着正确的方向前进。

我正在为如何以及在哪里引用HttpContext

这实际上很简单。在业务层中定义ISiteLocator,并在ASP.NET web应用程序中定义一个AspNetSiteLocator实现,最好是在CompositionRoot附近(或内部)。这个实现可能看起来像这样:

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更方便,因为消费者可能需要再次查询网站。然而,也许身份证是最方便的,但这取决于你自己。

如何[…]使用StructureMap生命周期优化

上面的实现没有任何状态,所以它可以在任何生存期内注册;例如,singleton。然而,对ISiteLocator.GetCurrentSite()的每次调用都会导致对ISiteRepository的新请求,这可能会导致太多的开销。在这种情况下,您可能想要一个将Site存储在私有字段中并始终返回该实例的实现。在这种情况下,您应该在"每个Web请求"的基础上注册该实现(因为SERVER_NAME在请求期间不会更改)。

最新更新