<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Grace.DependencyInjection;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Slabs.AspnetCore.Infrastructure;
using Slabs.AspnetCore.Tenant;

namespace Slabs.AspnetCore.Tenant
{
	public interface ITenant
	{
		string Name { get; set; }
	}

	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	public class Tenant : ITenant
	{
		private string DebuggerDisplay => $"Name: '{Name}'";

		public string Name { get; set; }

	}

	public static class Tenants
	{
		public static Tenant Cerberus = new Tenant
		{
			Name = "Cerberus"
		};

		public static Tenant Sketch7 = new Tenant
		{
			Name = "Sketch7"
		};

		private static readonly Dictionary<string, Tenant> _tenantsMap = new Dictionary<string, Tenant>
		{
			["local.cerberus.io"] = Cerberus,
			["local.sketch7.io"] = Sketch7,
		};

		public static Tenant ResolveByDomain(string domain)
		{
			_tenantsMap.TryGetValue(domain, out var tenant);
			return tenant;
		}
	}

	public class MultiTenantMiddleware
	{
		private readonly RequestDelegate _next;

		public MultiTenantMiddleware(
			RequestDelegate next
		)
		{
			_next = next;
		}

		public async Task Invoke(
			HttpContext httpContext
		)
		{
			var host = httpContext.Request.Host.Host;
			var tenant = Tenants.ResolveByDomain(host);

			var locatorScope = httpContext.RequestServices.GetService<IExportLocatorScope>();
			
			var r1 = locatorScope.Locate<RequestContext>();
			var r2 = locatorScope.Locate<RequestContext>();
			var scope = locatorScope.GetInjectionScope();
			scope.Configure(c => c.ExportInstance(tenant).As<ITenant>().Lifestyle.SingletonPerRequest());

			//using (var scope = locatorScope.GetInjectionScope().CreateChildScope(c =>
			//{

			//	c.ExportInstance(tenant).As<ITenant>();
			//}))
			//{
			var t = scope.Locate<ITenant>();

			httpContext.RequestServices = scope.Locate<IServiceProvider>();
			var r3 = locatorScope.Locate<RequestContext>();
			await _next(httpContext);
			//}
		}

	}
}

namespace Microsoft.AspNetCore.Builder
{
	public static class MultiTenantMiddlewareExtensions
	{
		public static IApplicationBuilder UseMultiTenant(this IApplicationBuilder builder)
			=> builder.UseMiddleware<MultiTenantMiddleware>();
	}
}<commit_msg>multi tenant - grace try childscope<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Grace.DependencyInjection;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Slabs.AspnetCore.Infrastructure;
using Slabs.AspnetCore.Tenant;

namespace Slabs.AspnetCore.Tenant
{
	public interface ITenant
	{
		string Name { get; set; }
	}

	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	public class Tenant : ITenant
	{
		private string DebuggerDisplay => $"Name: '{Name}'";

		public string Name { get; set; }

	}

	public static class Tenants
	{
		public static Tenant Cerberus = new Tenant
		{
			Name = "Cerberus"
		};

		public static Tenant Sketch7 = new Tenant
		{
			Name = "Sketch7"
		};

		private static readonly Dictionary<string, Tenant> _tenantsMap = new Dictionary<string, Tenant>
		{
			["local.cerberus.io"] = Cerberus,
			["local.sketch7.io"] = Sketch7,
		};

		public static Tenant ResolveByDomain(string domain)
		{
			_tenantsMap.TryGetValue(domain, out var tenant);
			return tenant;
		}
	}

	public class MultiTenantMiddleware
	{
		private readonly RequestDelegate _next;

		public MultiTenantMiddleware(
			RequestDelegate next
		)
		{
			_next = next;
		}

		public async Task Invoke(
			HttpContext httpContext
		)
		{
			var host = httpContext.Request.Host.Host;
			var tenant = Tenants.ResolveByDomain(host);

			var locatorScope = httpContext.RequestServices.GetService<IExportLocatorScope>();

			var r1 = locatorScope.Locate<RequestContext>();
			var r2 = locatorScope.Locate<RequestContext>();
			var injectionScope = locatorScope.GetInjectionScope();
			//injectionScope.Configure(c => c.ExportInstance(tenant).As<ITenant>().Lifestyle.SingletonPerRequest());

			using (var scope = injectionScope.CreateChildScope(c =>
			{
				// todo: get tenant container services + register
				c.ExportInstance(tenant).As<ITenant>();
			}, "tenant"))
			{
				var t = scope.Locate<ITenant>();

				httpContext.RequestServices = scope.Locate<IServiceProvider>();
				var r3 = locatorScope.Locate<RequestContext>();
				var r4 = scope.Locate<RequestContext>();
				await _next(httpContext);
			}
		}

	}
}

namespace Microsoft.AspNetCore.Builder
{
	public static class MultiTenantMiddlewareExtensions
	{
		public static IApplicationBuilder UseMultiTenant(this IApplicationBuilder builder)
			=> builder.UseMiddleware<MultiTenantMiddleware>();
	}
}
{'fraction_non_alphanumeric': 0.10923493850323118, 'fraction_numerical': 0.0031269543464665416, 'mean_word_length': 4.354910714285714, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6881108', 'n_tokens_mistral': 1687, 'n_tokens_neox': 1505, 'n_words': 320}