public TenantService(MultiTenantContext multiTenantContext, ITenantResolutionStrategy tenantResolutionStrategy, IOptions <AppSettings> appSettings) { _tenantResolutionStrategy = tenantResolutionStrategy; _multiTenantContext = multiTenantContext; _appSettings = appSettings.Value; }
private Tenant GetTenantFromUrl(String host) { if (String.IsNullOrEmpty(host)) { throw new ApplicationException("Host Url must be specified"); } Tenant tenant; string cacheName = "all-tenants-cache-name"; int cacheTimeOutSeconds = 30; List <Tenant> tenants = new Cache <List <Tenant> >().Get(cacheName, cacheTimeOutSeconds, () => { List <Tenant> tenantsFromCache; using (var context = new MultiTenantContext()) { tenantsFromCache = context.Tenants.ToList(); } return(tenantsFromCache); }); tenant = tenants.FirstOrDefault(a => a.DomainName.ToLower().Equals(host)) ?? tenants.FirstOrDefault(a => a.Default); if (tenant == null) { throw new ApplicationException("Tenant not found and, no default found"); } return(tenant); }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); using (var context = new MultiTenantContext()) { if (!context.Speakers.Any()) { context.Speakers.Add(new Speaker() { LastName = Guid.NewGuid().ToString("N") }); context.Sessions.Add(new Session() { Title = Guid.NewGuid().ToString("N") }); context.SaveChanges(); } } using (var context = new MultiTenantContext()) { if (!context.Tenants.Any()) { var tenants = new List<Tenant> { new Tenant { Name = "SVCC", DomainName = "www.siliconvalley-codecamp.com", Id = 1, Default = true }, new Tenant() { Name = "ANGU", DomainName = "angularu.com", Id = 3, Default = false }, new Tenant() { Name = "CSSC", DomainName = "codestarssummit.com", Id = 2, Default = false } }; context.Tenants.AddRange(tenants); context.SaveChanges(); } } }
public void AdjustOptionsNameOnGetOrAdd(string name) { var ti = new TenantInfo("test-id-123", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; var tca = new TestMultiTenantContextAccessor(tc); var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca); var options = new CookieAuthenticationOptions(); options.Cookie.Name = "a_name"; var options2 = new CookieAuthenticationOptions(); options2.Cookie.Name = "diff_name"; // Add new options. var result = cache.GetOrAdd(name, () => options); Assert.Equal(options.Cookie.Name, result.Cookie.Name); // Get the existing object. result = cache.GetOrAdd(name, () => options2); Assert.NotEqual(options2.Cookie.Name, result.Cookie.Name); // Confirm different tenant on same object is an add. ti.Id = "diff_id"; result = cache.GetOrAdd(name, () => options2); Assert.Equal(options2.Cookie.Name, result.Cookie.Name); }
private Tenant GetTenantBasedOnUrl(string urlhost) { if (string.IsNullOrEmpty(urlhost)) { throw new ApplicationException("urlHost must be specified"); } Tenant tenant; object Locker = new object(); var cacheName = "all-tenants-cache-name"; var cacheTimeoutSeconds = 30; List <Tenant> tenants = new TCache <List <Tenant> >().Get(cacheName, cacheTimeoutSeconds, () => { List <Tenant> tenants1; using (var context = new MultiTenantContext()) { tenants1 = context.Tenants.ToList(); } return(tenants1); }); tenant = tenants.FirstOrDefault(a => a.DomainName.ToLower().Equals(urlhost)) ?? tenants.FirstOrDefault(a => a.Default); return(tenant); }
public void RemoveOptionsForAllTenants(string name) { var ti = new TenantInfo("test-id-123", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; var tca = new TestMultiTenantContextAccessor(tc); var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca); var options = new CookieAuthenticationOptions(); // Add new options. var result = cache.TryAdd(name, options); Assert.True(result); // Add under a different tenant. ti.Id = "diff_id"; result = cache.TryAdd(name, options); Assert.True(result); // Remove all options and assert empty. result = cache.TryRemove(name); Assert.True(result); Assert.Empty((IEnumerable)cache.GetType().BaseType. GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance). GetValue(cache)); }
public async Task <ActionResult> Detail(string id = null) { using (var context = new MultiTenantContext()) { // add cache here var speakers = await context.Speakers.ToListAsync(); var speakerUrlDictionary = speakers.ToDictionary(k => k.SpeakerUrl); Speaker speaker = new Speaker(); if (speakerUrlDictionary.ContainsKey(id)) { speaker = speakerUrlDictionary[id]; speaker.ImageUrl = $"/Content/Images/Speakers/Speaker-{speaker.PictureId}-75.jpg"; var sessions = speaker.Sessions. Where(a => a.Tenant.Name == Tenant.Name). OrderBy(a => a.Title).ToList(); speaker.Sessions = sessions; } return(View("Detail", "_Layout", speaker)); } }
public void AddNamedOptionsForCurrentTenantOnlyOnAdd(string name) { var ti = new TenantInfo { Id = "test-id-123" }; var tc = new MultiTenantContext <TenantInfo>(); tc.TenantInfo = ti; var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; var cache = new MultiTenantOptionsCache <TestOptions, TenantInfo>(tca); var options = new TestOptions(); // Add new options. var result = cache.TryAdd(name, options); Assert.True(result); // Fail adding options under same name. result = cache.TryAdd(name, options); Assert.False(result); // Change the tenant id and confirm options can be added again. ti.Id = "diff_id"; result = cache.TryAdd(name, options); Assert.True(result); }
public void NotResetScopeIfNotApplicable() { var items = new Dictionary <object, object>(); var ti = new TenantInfo("test", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; items.Add(Finbuckle.MultiTenant.AspNetCore.Constants.HttpContextMultiTenantContext, tc); var httpContextMock = new Mock <HttpContext>(); httpContextMock.Setup(c => c.Items).Returns(items); httpContextMock.SetupProperty(c => c.RequestServices); var sc = new ServiceCollection(); sc.AddScoped <object>(_sp => DateTime.Now); var sp = sc.BuildServiceProvider(); httpContextMock.Object.RequestServices = sp; var ti2 = new TenantInfo("tenant2", null, null, null, null); var res = httpContextMock.Object.TrySetTenantInfo(ti2, false); Assert.Same(sp, httpContextMock.Object.RequestServices); Assert.StrictEqual <DateTime>((DateTime)sp.GetService <object>(), (DateTime)httpContextMock.Object.RequestServices.GetService <object>()); }
public void AdjustedOptionsNameOnAdd(string name) { var ti = new TenantInfo("test-id-123", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; var tca = new TestMultiTenantContextAccessor(tc); var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca); var options = new CookieAuthenticationOptions(); // Add new options. var result = cache.TryAdd(name, options); Assert.True(result); // Fail adding options under same name. result = cache.TryAdd(name, options); Assert.False(result); // Change the TC id and confirm options can be added again. ti.Id = "diff_id"; result = cache.TryAdd(name, options); Assert.True(result); }
private Tenant GetTenantBasedOnUrl(string urlHost) { if (String.IsNullOrEmpty(urlHost)) { throw new ApplicationException( "urlHost must be specified"); } Tenant tenant; string cacheName = "all-tenants-cache-name"; int cacheTimeOutSeconds = 2; // 2 seconds List <Tenant> tenants = new TCache <List <Tenant> >().Get( cacheName, cacheTimeOutSeconds, () => { List <Tenant> tenants1; using (var context = new MultiTenantContext()) { tenants1 = context.Tenants.ToList(); } return(tenants1); }); //List<Tenant> tenants = // (List<Tenant>) HttpContext.Current.Cache.Get(cacheName); //if (tenants == null) //{ // lock (Locker) // { // if (tenants == null) // { // using (var context = new MultiTenantContext()) // { // tenants = context.Tenants.ToList(); // HttpContext.Current.Cache.Insert(cacheName, tenants, null, // DateTime.Now.Add(new TimeSpan(0, 0, cacheTimeOutSeconds)), // TimeSpan.Zero); // } // } // } //} tenant = tenants. FirstOrDefault(a => a.DomainName.ToLower().Equals(urlHost)) ?? tenants.FirstOrDefault(a => a.Default); if (tenant == null) { throw new ApplicationException ("tenant not found based on URL, no default found"); } return(tenant); }
private Tenant GetTenantBasedOnUrl(string urlHost) { if (String.IsNullOrEmpty(urlHost)) { throw new ApplicationException("urlHost must be specified"); } Tenant tenant; string cacheName = "all-tenants-cache-name"; int cacheTimeOutSeconds = 30; List <Tenant> tenants = new TCache <List <Tenant> >().Get( cacheName, cacheTimeOutSeconds, () => { using (var context = new MultiTenantContext()) { return(context.Tenants.ToList()); } } ); tenant = tenants .FirstOrDefault(a => a.DomainName.Equals(urlHost, StringComparison.InvariantCultureIgnoreCase)) ?? tenants.FirstOrDefault(a => a.Default); if (tenant == null) { throw new ApplicationException("tenant not found based on URL, no default found"); } return(tenant); }
public void GetOrAddNamedOptionForCurrentTenantOnly(string name) { var ti = new TenantInfo("test-id-123", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; var tca = new TestMultiTenantContextAccessor(tc); var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca); var options = new CookieAuthenticationOptions(); options.Cookie.Name = "a_name"; var options2 = new CookieAuthenticationOptions(); options2.Cookie.Name = "diff_name"; // Add new options. var result = cache.GetOrAdd(name, () => options); Assert.Same(options, result); // Get the existing options if exists. result = cache.GetOrAdd(name, () => options2); Assert.NotSame(options2, result); // Confirm different tenant on same object is an add (ie it didn't exist there). ti.Id = "diff_id"; result = cache.GetOrAdd(name, () => options2); Assert.Same(options2, result); }
public void ThrowIfContructorParamIsNull() { var tc = new MultiTenantContext(); var tca = new TestMultiTenantContextAccessor(tc); Assert.Throws <ArgumentNullException>(() => new MultiTenantOptionsCache <CookieAuthenticationOptions>(null)); }
public void GetOrAddNamedOptionForCurrentTenantOnly(string name) { var ti = new TenantInfo { Id = "test-id-123" }; var tc = new MultiTenantContext <TenantInfo>(); tc.TenantInfo = ti; var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; var cache = new MultiTenantOptionsCache <TestOptions, TenantInfo>(tca); var options = new TestOptions(); var options2 = new TestOptions(); // Add new options. var result = cache.GetOrAdd(name, () => options); Assert.Same(options, result); // Get the existing options if exists. result = cache.GetOrAdd(name, () => options2); Assert.NotSame(options2, result); // Confirm different tenant on same object is an add (ie it didn't exist there). ti.Id = "diff_id"; result = cache.GetOrAdd(name, () => options2); Assert.Same(options2, result); }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); using (var context = new MultiTenantContext()) { if (!context.Speakers.Any()) { context.Speakers.Add(new Speaker() { LastName = Guid.NewGuid().ToString("N") }); context.Sessions.Add(new Session() { Title = Guid.NewGuid().ToString("N") }); context.SaveChanges(); } } using (var context = new MultiTenantContext()) { if (!context.Tenants.Any()) { var tenants = new List <Tenant> { new Tenant { Name = "SVCC", DomainName = "www.siliconvalley-codecamp.com", Id = 1, Default = true }, new Tenant() { Name = "ANGU", DomainName = "angularu.com", Id = 3, Default = false }, new Tenant() { Name = "CSSC", DomainName = "codestarssummit.com", Id = 2, Default = false } }; context.Tenants.AddRange(tenants); context.SaveChanges(); } } }
public void ThrowsIfGetOrAddFactoryIsNull() { var tc = new MultiTenantContext(); var tca = new TestMultiTenantContextAccessor(tc); var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca); Assert.Throws <ArgumentNullException>(() => cache.GetOrAdd("", null)); }
public void ThrowIfContructorParamIsNull() { var tc = new MultiTenantContext <TenantInfo>(); var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; Assert.Throws <ArgumentNullException>(() => new MultiTenantOptionsCache <TestOptions, TenantInfo>(null)); }
public ActionResult Index() { using (var context = new MultiTenantContext()) { var tenants = context.Tenant.ToList(); return(View("Index", tenants)); } }
public async Task<ActionResult> Index() { using (var context = new MultiTenantContext()) { var tenants = await context.Tenants.ToListAsync(); return View(tenants); } }
public async Task <ActionResult> Index() { using (var context = new MultiTenantContext()) { var tenants = await context.Tenants.ToListAsync(); return(View(tenants)); } }
public void ThrowsIfGetOrAddFactoryIsNull() { var tc = new MultiTenantContext <TenantInfo>(); var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; var cache = new MultiTenantOptionsCache <TestOptions, TenantInfo>(tca); Assert.Throws <ArgumentNullException>(() => cache.GetOrAdd("", null)); }
public void RemoveNamedOptionsForCurrentTenantOnly(string name) { var ti = new TenantInfo { Id = "test-id-123" }; var tc = new MultiTenantContext <TenantInfo>(); tc.TenantInfo = ti; var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; var cache = new MultiTenantOptionsCache <TestOptions, TenantInfo>(tca); var options = new TestOptions(); // Add new options. var result = cache.TryAdd(name, options); Assert.True(result); // Add under a different tenant. ti.Id = "diff_id"; result = cache.TryAdd(name, options); Assert.True(result); result = cache.TryAdd("diffname", options); Assert.True(result); // Remove named options for current tenant. result = cache.TryRemove(name); Assert.True(result); var tenantCache = (ConcurrentDictionary <string, IOptionsMonitorCache <TestOptions> >)cache.GetType(). GetField("map", BindingFlags.NonPublic | BindingFlags.Instance). GetValue(cache); dynamic tenantInternalCache = tenantCache[ti.Id].GetType().GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(tenantCache[ti.Id]); // Assert named options removed and other options on tenant left as-is. Assert.False(tenantInternalCache.Keys.Contains(name ?? "")); Assert.True(tenantInternalCache.Keys.Contains("diffname")); // Assert other tenant not affected. ti.Id = "test-id-123"; tenantInternalCache = tenantCache[ti.Id].GetType().GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(tenantCache[ti.Id]); Assert.True(tenantInternalCache.ContainsKey(name ?? "")); }
public async Task <ActionResult> Index() { using (var context = new MultiTenantContext()) { var sessions = await context.Sessions.Where(a => a.Tenant.Name == Tenant.Name). OrderBy(a => a.Title.ToLower()).ToListAsync(); foreach (var session in sessions) { foreach (var speaker in session.Speakers) { speaker.ImageUrl = $"/Content/Images/Speakers/Speaker-{speaker.PictureId}-75.jpg"; } } return(View("Index", "_Layout", sessions)); } }
private static void SetStrategyInfo(MultiTenantContext multiTenantContext, IMultiTenantStrategy strategy) { var strategyInfo = new StrategyInfo(); strategyInfo.MultiTenantContext = multiTenantContext; strategyInfo.Strategy = strategy; if (strategy.GetType().IsGenericType&& strategy.GetType().GetGenericTypeDefinition() == typeof(MultiTenantStrategyWrapper <>)) { strategyInfo.StrategyType = strategy.GetType().GetGenericArguments().First(); } else { strategyInfo.StrategyType = strategy.GetType(); } multiTenantContext.StrategyInfo = strategyInfo; }
public void GetTenantContextIfExists() { var items = new Dictionary <object, object>(); var ti = new TenantInfo("test", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; items.Add(Finbuckle.MultiTenant.AspNetCore.Constants.HttpContextMultiTenantContext, tc); var httpContextMock = new Mock <HttpContext>(); httpContextMock.Setup(c => c.Items).Returns(items); var mtc = httpContextMock.Object.GetMultiTenantContext(); Assert.Same(tc, mtc); }
public void CallOriginalPrincipalValidation() { var services = new ServiceCollection(); services.AddLogging(); var called = false; services.AddAuthentication().AddCookie(options => { #pragma warning disable 1998 options.Events.OnValidatePrincipal = async _ => #pragma warning restore 1998 { called = true; }; }); services.AddMultiTenant <TenantInfo>() .WithPerTenantAuthentication(); var sp = services.BuildServiceProvider(); // Fake a resolved tenant var mtc = new MultiTenantContext <TenantInfo>(); mtc.TenantInfo = new TenantInfo { Identifier = "abc" }; sp.GetRequiredService <IMultiTenantContextAccessor <TenantInfo> >().MultiTenantContext = mtc; // Trigger the ValidatePrincipal event var httpContextMock = new Mock <HttpContext>(); httpContextMock.Setup(c => c.RequestServices).Returns(sp); httpContextMock.Setup(c => c.Items).Returns(new Dictionary <object, object?>()); var scheme = sp.GetRequiredService <IAuthenticationSchemeProvider>() .GetSchemeAsync(CookieAuthenticationDefaults.AuthenticationScheme).Result; var options = sp.GetRequiredService <IOptionsMonitor <CookieAuthenticationOptions> >().Get(CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(new ClaimsIdentity()); var authTicket = new AuthenticationTicket(principal, CookieAuthenticationDefaults.AuthenticationScheme); authTicket.Properties.Items[Constants.TenantToken] = "abc"; var cookieValidationContext = new CookieValidatePrincipalContext(httpContextMock.Object, scheme !, options, authTicket); options.Events.ValidatePrincipal(cookieValidationContext).Wait(); Assert.True(called); }
public void ClearOptionsForCurrentTenantOnly() { var ti = new TenantInfo { Id = "test-id-123" }; var tc = new MultiTenantContext <TenantInfo>(); tc.TenantInfo = ti; var tca = new MultiTenantContextAccessor <TenantInfo>(); tca.MultiTenantContext = tc; var cache = new MultiTenantOptionsCache <TestOptions, TenantInfo>(tca); var options = new TestOptions(); // Add new options. var result = cache.TryAdd("", options); Assert.True(result); // Add under a different tenant. ti.Id = "diff_id"; result = cache.TryAdd("", options); Assert.True(result); // Clear options on first tenant. ti.Id = "test-id-123"; cache.Clear(); // Assert options cleared on this tenant. var tenantCache = (ConcurrentDictionary <string, IOptionsMonitorCache <TestOptions> >)cache.GetType(). GetField("map", BindingFlags.NonPublic | BindingFlags.Instance). GetValue(cache); dynamic tenantInternalCache = tenantCache[ti.Id].GetType().GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(tenantCache[ti.Id]); Assert.True(tenantInternalCache.IsEmpty); // Assert options still exist on other tenant. ti.Id = "diff_id"; tenantInternalCache = tenantCache[ti.Id].GetType().GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance) .GetValue(tenantCache[ti.Id]); Assert.False(tenantInternalCache.IsEmpty); }
private Tenant GetTenantBasedOnUrl(string urlHost) { if (string.IsNullOrEmpty(urlHost)) { throw new ApplicationException("urlHose was Null"); } using (var context = new MultiTenantContext()) { var tenants = context.Tenants.ToList(); var currentTenant = tenants.FirstOrDefault(a => a.Domain.ToLower().Equals(urlHost)) ?? tenants.FirstOrDefault(a => a.Default); if (currentTenant == null) { throw new ApplicationException("No tenant found."); } return(currentTenant); } }
public void SetTenantInfo() { var items = new Dictionary <object, object>(); var ti = new TenantInfo("test", null, null, null, null); var tc = new MultiTenantContext(); tc.TenantInfo = ti; items.Add(Finbuckle.MultiTenant.AspNetCore.Constants.HttpContextMultiTenantContext, tc); var httpContextMock = new Mock <HttpContext>(); httpContextMock.Setup(c => c.Items).Returns(items); var ti2 = new TenantInfo("tenant2", null, null, null, null); var res = httpContextMock.Object.TrySetTenantInfo(ti2, false); Assert.True(res); Assert.Same(ti2, httpContextMock.Object.GetMultiTenantContext().TenantInfo); }
public void SkipPrincipalValidationIfBypassSet_WithClaimStrategy() { var services = new ServiceCollection(); services.AddLogging(); var called = false; #pragma warning disable 1998 services.AddAuthentication().AddCookie(o => o.Events.OnValidatePrincipal = async _ => called = true); #pragma warning restore 1998 services.AddMultiTenant <TenantInfo>() .WithClaimStrategy(); var sp = services.BuildServiceProvider(); // Fake a resolved tenant var mtc = new MultiTenantContext <TenantInfo> { TenantInfo = new TenantInfo { Identifier = "abc1" } }; sp.GetRequiredService <IMultiTenantContextAccessor <TenantInfo> >().MultiTenantContext = mtc; // Trigger the ValidatePrincipal event var httpContextMock = new Mock <HttpContext>(); httpContextMock.Setup(c => c.RequestServices).Returns(sp); var httpContextItems = new Dictionary <object, object?>(); httpContextItems[$"{Constants.TenantToken}__bypass_validate_principal__"] = true; httpContextMock.Setup(c => c.Items).Returns(httpContextItems); var scheme = sp.GetRequiredService <IAuthenticationSchemeProvider>() .GetSchemeAsync(CookieAuthenticationDefaults.AuthenticationScheme).Result; var options = sp.GetRequiredService <IOptionsMonitor <CookieAuthenticationOptions> >().Get(CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(new ClaimsIdentity()); var authTicket = new AuthenticationTicket(principal, CookieAuthenticationDefaults.AuthenticationScheme); authTicket.Properties.Items[Constants.TenantToken] = "abc2"; var cookieValidationContext = new CookieValidatePrincipalContext(httpContextMock.Object, scheme !, options, authTicket); options.Events.ValidatePrincipal(cookieValidationContext).Wait(); Assert.NotNull(cookieValidationContext.Principal); Assert.False(called); }
public RustStoreStorePaymentService(IHttpContextAccessor httpContextAccessor, IConfiguration configuration, ILogger <RustStoreStorePaymentService> logger, PayPalSettings payPalSettings, ISteamUserService steamUserService, EasyShopContext easyShopContext, IPayPalCreatedPaymentService payPalCreatedPaymentService, IPayPalExecutedPaymentService payPalExecutedPaymentService) { _httpContextAccessor = httpContextAccessor; _configuration = configuration; _logger = logger; _payPalSettings = payPalSettings; _steamUserService = steamUserService; _easyShopContext = easyShopContext; _payPalCreatedPaymentService = payPalCreatedPaymentService; _payPalExecutedPaymentService = payPalExecutedPaymentService; _hostString = $"{httpContextAccessor.HttpContext.Request.Scheme}://{httpContextAccessor.HttpContext.Request.Host}"; _multiTenantContext = httpContextAccessor.HttpContext.GetMultiTenantContext(); }