注入

时间:2017-04-05 09:29:00

标签: c# asp.net-core httpcontext

我目前正在开发一个系统,该系统需要依赖于来自不同网站设​​置的请求来自哪个域(例如,默认语言ID),然后在应用程序的其余部分中使用该系统。这些设置存储在类WebsiteSettings中,在需要时将其注入应用程序的其余部分。

我尝试的第一个选项是在我的HttpContext方法中注册服务以访问ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    //Register other services

    services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>();
    services.TryAddScoped<WebsiteSettingsFiller>();
    services.TryAddScoped(typeof(WebsiteSettings), s =>
    {
        var settingFiller = s.GetService<WebsiteSettingsFiller>();
        return settingFiller.Create();
    });
}

接下来,在我的WebsiteSettingsFiller服务中,我会注入IHttpContextAccessor以及加载网站设置所需的其他一些服务。

public class WebsiteSettingsFiller
{
    protected readonly IRepository Database;
    private readonly IHttpContextAccessor _accessor;
    private readonly StartupSitePropertyService _sitePropertyService;
    private IQueryable<Site> AllSites => Database.All<Site>();
    private IQueryable<SiteLanguage> AllSiteLanguages => Database.All<SiteLanguage>();

    public WebsiteSettingsFiller(IRepository db, StartupSitePropertyService siteProperties, IHttpContextAccessor accessor)
    {
        Database = db;
        _accessor = accessor;
        _sitePropertyService = siteProperties;
    }

    public WebsiteSettings Create()
    {
        var domain = _accessor.HttpContext.Request.Host.Host; //null exception on this line
#if DEBUG
        domain = "www.somewebsite.com";
#endif
        var config = GetConfigByDomain(domain);
        return config;
    }

    private WebsiteSettings GetConfigByDomain(string domain)
    {
        var site = AllSites.OrderByDescending(s => s.Created).FirstOrDefault(t => t.Host == domain);
        if (site == null) return null;
        var languages = AllSiteLanguages.Where(sl => sl.SiteId == site.Id).ToList();
        //get more variables 
        return new WebsiteSettings
        {
            /* Set variables */
        }
    }
}

示例注入WebsiteSettings

public class RouteService : BaseService
{
    private IDictionary<int, string> _routeLanguages = null;
    private readonly WebsiteRedisService _websiteRedisService;

    public RouteService(IRepository db,
        WebsiteSettings settings,
        WebsiteRedisService websiteRedisService)
        : base(db, settings)
    {
        _websiteRedisService = websiteRedisService;
    }

    public async Task<IDictionary<int, string>> RouteLanguagesAsync()
    {
        return _routeLanguages ??
               (_routeLanguages = await _websiteRedisService.SiteLanguagesToAsync(Settings.SiteId));
    }
}

可悲的是,无论我尝试什么,HttpContext引用始终为null。有谁知道我可以尝试解决这个问题?或者我只是以错误的方式解决这个问题?非常感谢任何建议!

1 个答案:

答案 0 :(得分:1)

IHttpContextAccessor应该作为Singleton注入。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

WebsiteSettingsFiller中,您可以在构造函数中获取HttpContext并分配到HttpContext字段。

public class WebsiteSettingsFiller
{
    //private readonly IHttpContextAccessor _accessor;
    private readonly HttpContext _context;

    public WebsiteSettingsFiller(IHttpContextAccessor accessor)
    {
        //_accessor = accessor;
        _context = accessor.HttpContext;
    }
}