零框架多租户设计方案
This commit is contained in:
1 parent
b7caaa2d0c
commit
b4a704526d
42 files changed
+1002
-1
No files matched your search
@@ -0,0 +1,28 @@
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public class CurrentTenant : ICurrentTenant
|
||||
{
|
||||
public string? TenantId { get; private set; }
|
||||
|
||||
public IDisposable SetTenant(string? tenantId)
|
||||
{
|
||||
string? parentTenantId = TenantId;
|
||||
|
||||
TenantId = tenantId;
|
||||
|
||||
return new DisposeAction(() =>
|
||||
{
|
||||
TenantId = parentTenantId;
|
||||
});
|
||||
}
|
||||
|
||||
public class DisposeAction(Action action) : IDisposable
|
||||
{
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
action();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public interface ICurrentTenant
|
||||
{
|
||||
string? TenantId { get; }
|
||||
|
||||
IDisposable SetTenant(string? tenantId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public interface ITenantIdProvider
|
||||
{
|
||||
Task<string?> GetTenantIdAsync();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public static class MultiTenancyExtensions
|
||||
{
|
||||
public static IServiceCollection AddMultiTenancy(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<ICurrentTenant, CurrentTenant>();
|
||||
services.AddScoped<ITenantIdProvider, TenantIdProvider>();
|
||||
|
||||
return services.AddScoped<TenantMiddleware>();
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseMultiTenancy(this IApplicationBuilder app)
|
||||
{
|
||||
app.UseMiddleware<TenantMiddleware>();
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"profiles": {
|
||||
"MultiTenancySample.ServiceDefaults": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:61544;http://localhost:61545"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public class TenantIdProvider(IHttpContextAccessor httpContextAccessor) : ITenantIdProvider
|
||||
{
|
||||
public async Task<string?> GetTenantIdAsync()
|
||||
{
|
||||
HttpContext httpContext = httpContextAccessor.HttpContext ?? new DefaultHttpContext();
|
||||
|
||||
const string tenantKey = "tenant";
|
||||
|
||||
if (httpContext.Request.Headers.TryGetValue(tenantKey, out var headerValues))
|
||||
{
|
||||
return headerValues.First();
|
||||
}
|
||||
|
||||
if (httpContext.Request.Query.TryGetValue(tenantKey, out var queryValues))
|
||||
{
|
||||
return queryValues.First();
|
||||
}
|
||||
|
||||
if (httpContext.Request.Cookies.TryGetValue(tenantKey, out var cookieValue))
|
||||
{
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
if (httpContext.Request.RouteValues.TryGetValue(tenantKey, out var routeValue))
|
||||
{
|
||||
return routeValue?.ToString();
|
||||
}
|
||||
|
||||
return await Task.FromResult<string?>(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace MultiTenancySample.ServiceDefaults
|
||||
{
|
||||
public class TenantMiddleware(ICurrentTenant currentTenant, ITenantIdProvider tenantProvider) : IMiddleware
|
||||
{
|
||||
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||
{
|
||||
string? tenantId = await tenantProvider.GetTenantIdAsync();
|
||||
|
||||
using (currentTenant.SetTenant(tenantId))
|
||||
{
|
||||
await next(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user