【问题标题】:Injecting host from HttpContext into Service layer将 HttpContext 中的主机注入服务层
【发布时间】:2012-09-28 16:48:27
【问题描述】:

我需要通过在我的 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 生命周期对其进行优化。

【问题讨论】:

    标签: c# dependency-injection structuremap httpcontext asp.net-web-api


    【解决方案1】:

    我想我需要在我的服务层中注入一个 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 在请求期间不会更改)。

    【讨论】:

    • 我正在努力实现这一点,一旦工作将标记为答案。将 ISiteLocator 注入到我的 DbContext 中发生了一些奇怪的事情,更糟糕的是,Web API 隐藏了实际的异常并给了我“没有默认构造函数”。希望不会太长..
    猜你喜欢
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多