我目前正在开发一个系统,该系统需要依赖于来自不同网站设置的请求来自哪个域(例如,默认语言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。有谁知道我可以尝试解决这个问题?或者我只是以错误的方式解决这个问题?非常感谢任何建议!
答案 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;
}
}