我目前正在開發一個系統,其中依賴於來自不同網站設置的請求來自哪個域需要加載(例如默認語言ID),然後在應用程序的其餘部分中使用該系統。這些設置存儲在類WebsiteSettings
中,需要時將其注入應用程序的其餘部分。IHttpContextAccessor null注入後
我嘗試的第一個選項是註冊服務在我ConfigureServices
方法做這個訪問HttpContext
:
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引用總是空。有誰知道我可以嘗試解決這個問題嗎?或者我只是以錯誤的方式來解決這個問題?任何建議,非常感謝!
嘗試註冊爲單:'services.TryAddSingleton();' –
Evk
可悲沒有解決的問題。另外我認爲它需要'TryAddScoped',因爲'HttpContext'訪問器每個請求都會改變,對吧? – nbokmans
在這[issue](https://github.com/aspnet/Hosting/issues/793)中聲稱HttpContextAccessor應該被註冊爲singleton,否則它將無法工作(因爲它的內部實現)。 – Evk