I'm currently developing a system where dependent on what domain a request comes from different website settings need to be loaded (eg. default language id) which is then used in the rest of the application. These settings are stored in a class WebsiteSettings
which are injected into the rest of the application when needed.
The first option I tried was registering a service to access the HttpContext
by doing this in my ConfigureServices
method:
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();
});
}
Next, in my WebsiteSettingsFiller
service, I inject the IHttpContextAccessor
and some other services that I need to load the site settings.
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 */
}
}
}
Example injection of 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));
}
}
Sadly, no matter what I try the HttpContext reference is always null. Does anyone have any idea what I can try to resolve this? Or am I just approaching this problem the wrong way? Any suggestions are greatly appreciated!