C# 将主机从HttpContext注入服务层

C# 将主机从HttpContext注入服务层,c#,dependency-injection,structuremap,httpcontext,asp.net-web-api,C#,Dependency Injection,Structuremap,Httpcontext,Asp.net Web Api,我需要通过请求Web API服务中所有数据库调用的主机名来应用过滤 此过滤的工作原理如下: public IEnumerable<Profiles> GetProfiles () { var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"]; return profilesService.Get(host); } 根据请求的主机名查找要配置文件的站点 在请求中进行的所有后续数据访问调用上应用Sit

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

此过滤的工作原理如下:

public IEnumerable<Profiles> GetProfiles ()
{
 var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
 return profilesService.Get(host);
}
  • 根据请求的主机名查找要配置文件的站点
  • 在请求中进行的所有后续数据访问调用上应用Site.Id
  • 本质上是一个全局过滤器,以便API服务返回的数据始终包含在主机中

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

    public IEnumerable<Profiles> GetProfiles ()
    {
     var host = HttpContext.Current.Request.ServerVariables["SERVER_NAME"];
     return profilesService.Get(host);
    }
    
    public IEnumerable GetProfiles()
    {
    var host=HttpContext.Current.Request.ServerVariables[“服务器名称”];
    返回profilesService.Get(主机);
    }
    
    但是,由于这是所有请求的一致规则,我想用一种更优雅的方法来处理它,所以我的服务调用就是profileSerivce.Get()

    我认为我需要在我的服务层中注入一个ISiteLocator,它要么具有主机名,要么甚至更好,具有从数据库中检索到的Id,然后我可以应用该Id。但我正在努力解决这个问题:如何以及在哪里引用HttpContext来获取主机名,以及是否可以使用StructureMap生命周期对此进行优化

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

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

    我正在为如何以及在何处引用 HttpContext

    这其实很简单。在业务层中定义
    ISiteLocator
    ,并在ASP.NET web应用程序中定义
    AspNetSiteLocator
    实现,最好靠近(或在)您的应用程序内部。该实现可能如下所示:

    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
    以最方便该定位器使用者的方式返回数据。在我的示例中,我返回了一个
    站点
    实体(如果您的域中有这样的实体)。这可能比主机名或Id更方便,因为消费者可能需要自己再次查询站点。然而,也许身份证是最方便的,但这取决于你去发现

    如何[…]使用StructureMap生命周期对此进行优化


    上述实现没有任何状态,因此可以在任何生存期内注册;例如,辛格尔顿。但是,每次调用
    ISiteLocator.GetCurrentSite()
    都会导致对
    ISiteRepository
    的新请求,这可能会导致太多开销。在这种情况下,您可能希望实现将
    站点
    存储在私有字段中,并始终返回该实例。在这种情况下,您应该在“每个Web请求”的基础上注册该实现(因为
    服务器名称在请求过程中不会更改)。

    我正在努力实现这一点,并将在工作后标记为答案。将ISiteLocator注入我的DbContext时发生了一些奇怪的事情,更糟糕的是,Web API隐藏了实际的异常,并给了我“没有默认构造函数”。希望不会太久。。