feat: 添加多租户模块
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户信息
|
||||||
|
/// </summary>
|
||||||
|
public class BasicTenantInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID
|
||||||
|
/// </summary>
|
||||||
|
public Guid? TenantId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID 名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public BasicTenantInfo(Guid? tenantId, string? name = null)
|
||||||
|
{
|
||||||
|
TenantId = tenantId;
|
||||||
|
Name = name ?? string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using Yi.Framework.Core.Utils;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前租户实现
|
||||||
|
/// </summary>
|
||||||
|
public class CurrentTenant : ICurrentTenant
|
||||||
|
{
|
||||||
|
private readonly ICurrentTenantAccessor _currentTenantAccessor;
|
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public CurrentTenant(ICurrentTenantAccessor currentTenantAccessor)
|
||||||
|
{
|
||||||
|
_currentTenantAccessor = currentTenantAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否有效
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool IsAvailable => Id != Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID
|
||||||
|
/// </summary>
|
||||||
|
public virtual Guid Id => _currentTenantAccessor.Current?.TenantId ?? Guid.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户名称
|
||||||
|
/// </summary>
|
||||||
|
public string? Name => _currentTenantAccessor.Current?.Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 替换租户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IDisposable Change(Guid? id, string? name = null)
|
||||||
|
{
|
||||||
|
return SetCurrent(id, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置当前租户
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private IDisposable SetCurrent(Guid? tenantId, string? name = null)
|
||||||
|
{
|
||||||
|
BasicTenantInfo? parentScope = _currentTenantAccessor.Current;
|
||||||
|
_currentTenantAccessor.Current = new BasicTenantInfo(tenantId, name);
|
||||||
|
|
||||||
|
return new DisposeAction<ValueTuple<ICurrentTenantAccessor, BasicTenantInfo>>(static ((ICurrentTenantAccessor, BasicTenantInfo) state) =>
|
||||||
|
{
|
||||||
|
(ICurrentTenantAccessor currentTenantAccessor, BasicTenantInfo parentScope) = state;
|
||||||
|
currentTenantAccessor.Current = parentScope;
|
||||||
|
},
|
||||||
|
(_currentTenantAccessor, parentScope));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认租户访问器实现
|
||||||
|
/// </summary>
|
||||||
|
public class DefaultCurrentTenantAccessor : ICurrentTenantAccessor
|
||||||
|
{
|
||||||
|
private ITenantResolver _tenantResolver;
|
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public DefaultCurrentTenantAccessor(ITenantResolver tenantResolver)
|
||||||
|
{
|
||||||
|
_tenantResolver = tenantResolver;
|
||||||
|
TenantResolveResult? tenantResolveResult = _tenantResolver.ResolveTenantIdOrNameAsync().Result;
|
||||||
|
string? tenantIdStr = tenantResolveResult.TenantIdOrName;
|
||||||
|
|
||||||
|
Current = Guid.TryParse(tenantIdStr, out Guid tehnantId)
|
||||||
|
? new BasicTenantInfo(tehnantId)
|
||||||
|
: new BasicTenantInfo(Guid.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前租户信息
|
||||||
|
/// </summary>
|
||||||
|
public BasicTenantInfo Current { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Yi.Framework.MultiTenancy.ResolveContributor;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy.Extensions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户注入扩展方法
|
||||||
|
/// </summary>
|
||||||
|
public static class MultiTenancyExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注入 租户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static IServiceCollection AddCurrentTenant(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.Configure<TenantResolveOptions>(option =>
|
||||||
|
{
|
||||||
|
//添加租户解析器,默认添加从当前用户中获取
|
||||||
|
|
||||||
|
//添加从httpheader,解析TenantId配置的租户id
|
||||||
|
option.TenantResolvers.Add(new HttpHeaderTenantResolveContributor());
|
||||||
|
|
||||||
|
//添加配置租户解析器,解析TenantId配置的租户id
|
||||||
|
option.TenantResolvers.Add(new ConfigurationTenantResolveContributor());
|
||||||
|
});
|
||||||
|
|
||||||
|
//添加租户解析器注入
|
||||||
|
services.AddTransient<ITenantResolver, TenantResolver>();
|
||||||
|
|
||||||
|
//添加当前租户
|
||||||
|
services.AddTransient<ICurrentTenant, CurrentTenant>();
|
||||||
|
|
||||||
|
//添加默认访问器
|
||||||
|
services.AddTransient<ICurrentTenantAccessor, DefaultCurrentTenantAccessor>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前租户接口
|
||||||
|
/// </summary>
|
||||||
|
public interface ICurrentTenant
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否有效
|
||||||
|
/// </summary>
|
||||||
|
bool IsAvailable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID
|
||||||
|
/// </summary>
|
||||||
|
Guid Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户名称
|
||||||
|
/// </summary>
|
||||||
|
string? Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 替换租户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
IDisposable Change(Guid? id, string? name = null);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户访问器
|
||||||
|
/// </summary>
|
||||||
|
public interface ICurrentTenantAccessor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前租户信息
|
||||||
|
/// </summary>
|
||||||
|
BasicTenantInfo Current { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析器上下文
|
||||||
|
/// (作用于各个<see cref="ITenantResolveContributor.ResolveAsync(ITenantResolveContext)"/>)之间
|
||||||
|
/// </summary>
|
||||||
|
public interface ITenantResolveContext
|
||||||
|
{
|
||||||
|
/// <summary/>
|
||||||
|
IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID 或 名称
|
||||||
|
/// </summary>
|
||||||
|
string TenantIdOrName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已处理
|
||||||
|
/// </summary>
|
||||||
|
bool Handled { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户解析器贡献者
|
||||||
|
/// </summary>
|
||||||
|
public interface ITenantResolveContributor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 贡献者名称
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">解析器上下文</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task ResolveAsync(ITenantResolveContext context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户解析器接口
|
||||||
|
/// </summary>
|
||||||
|
public interface ITenantResolver
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 解析租户Id或名称
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<TenantResolveResult> ResolveTenantIdOrNameAsync();
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Yi.Framework.Data.Entities;
|
||||||
|
using Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy.ResolveContributor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="IConfiguration"/>租户解析器贡献者
|
||||||
|
/// </summary>
|
||||||
|
public class ConfigurationTenantResolveContributor : TenantResolveContributorBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 租户解析器贡献者基类
|
||||||
|
/// </summary>
|
||||||
|
public override string Name => "Configuration";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">解析器上下文</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override Task ResolveAsync(ITenantResolveContext context)
|
||||||
|
{
|
||||||
|
IConfiguration? configuration = context.ServiceProvider.GetRequiredService<IConfiguration>();
|
||||||
|
|
||||||
|
string? tenantIdStr = configuration.GetValue<string>(nameof(IMultiTenant.TenantId));
|
||||||
|
|
||||||
|
if (Guid.TryParse(tenantIdStr, out Guid tenantId))
|
||||||
|
{
|
||||||
|
if (tenantId != Guid.Empty)
|
||||||
|
{
|
||||||
|
context.TenantIdOrName = tenantId.ToString();
|
||||||
|
context.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Handled = false;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Yi.Framework.Core.CurrentUsers;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy.ResolveContributor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前用户中获取租户
|
||||||
|
/// </summary>
|
||||||
|
public class CurrentUserTenantResolveContributor : TenantResolveContributorBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 贡献者名称
|
||||||
|
/// </summary>
|
||||||
|
public const string ContributorName = "CurrentUser";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 贡献者名称
|
||||||
|
/// </summary>
|
||||||
|
public override string Name => ContributorName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">解析器上下文</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override Task ResolveAsync(ITenantResolveContext context)
|
||||||
|
{
|
||||||
|
ICurrentUser currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
|
||||||
|
if (currentUser.TenantId != Guid.Empty)
|
||||||
|
{
|
||||||
|
context.Handled = true;
|
||||||
|
context.TenantIdOrName = currentUser.TenantId.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Handled = false;
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Yi.Framework.Data.Entities;
|
||||||
|
using Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy.ResolveContributor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="HttpContext"/>租户解析器贡献者
|
||||||
|
/// </summary>
|
||||||
|
public class HttpHeaderTenantResolveContributor : TenantResolveContributorBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 贡献者名称
|
||||||
|
/// </summary>
|
||||||
|
public override string Name => "HttpHeader";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">解析器上下文</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override Task ResolveAsync(ITenantResolveContext context)
|
||||||
|
{
|
||||||
|
IHttpContextAccessor? httpContextAccessor = context.ServiceProvider.GetService<IHttpContextAccessor>();
|
||||||
|
|
||||||
|
//如果没有注入http对象,直接跳出
|
||||||
|
if (httpContextAccessor is null)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
HttpContext? httpContext = httpContextAccessor.HttpContext;
|
||||||
|
if (httpContext is not null)
|
||||||
|
{
|
||||||
|
string? tenantId = httpContext.Request.Headers
|
||||||
|
.Where(x => x.Key == nameof(IMultiTenant.TenantId))
|
||||||
|
.Select(x => x.Value.ToString())
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (tenantId is not null)
|
||||||
|
{
|
||||||
|
if (Guid.TryParse(tenantId, out Guid tid))
|
||||||
|
{
|
||||||
|
context.TenantIdOrName = tid.ToString();
|
||||||
|
context.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析器上下文
|
||||||
|
/// </summary>
|
||||||
|
public class TenantResolveContext : ITenantResolveContext
|
||||||
|
{
|
||||||
|
/// <summary/>
|
||||||
|
public TenantResolveContext(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
ServiceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary/>
|
||||||
|
public IServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID 或 名称
|
||||||
|
/// </summary>
|
||||||
|
public string TenantIdOrName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已处理
|
||||||
|
/// </summary>
|
||||||
|
public bool Handled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已经处理或者<see cref="TenantIdOrName"/>为有效值
|
||||||
|
/// </summary>
|
||||||
|
public bool HasResolvedTenantOrHost()
|
||||||
|
{
|
||||||
|
return Handled
|
||||||
|
|| TenantIdOrName != Guid.Empty.ToString() && !string.IsNullOrWhiteSpace(TenantIdOrName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户解析器贡献者基类
|
||||||
|
/// </summary>
|
||||||
|
public abstract class TenantResolveContributorBase : ITenantResolveContributor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 贡献者名称
|
||||||
|
/// </summary>
|
||||||
|
public abstract string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">解析器上下文</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public abstract Task ResolveAsync(ITenantResolveContext context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
using Yi.Framework.MultiTenancy.ResolveContributor;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析器属性
|
||||||
|
/// </summary>
|
||||||
|
public class TenantResolveOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
public TenantResolveOptions()
|
||||||
|
{
|
||||||
|
TenantResolvers = new List<ITenantResolveContributor>
|
||||||
|
{
|
||||||
|
new CurrentUserTenantResolveContributor()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析器贡献者。由这帮东西为框架提供 租户ID
|
||||||
|
/// </summary>
|
||||||
|
public List<ITenantResolveContributor> TenantResolvers { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户解析器结果
|
||||||
|
/// </summary>
|
||||||
|
public class TenantResolveResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 租户ID 或 名称
|
||||||
|
/// </summary>
|
||||||
|
public string TenantIdOrName { get; set; } = Guid.Empty.ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 存储遍历过的<see cref="ITenantResolveContributor.Name"/>
|
||||||
|
/// </summary>
|
||||||
|
public List<string> AppliedResolvers { get; } = new List<string>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public class TenantResolver : ITenantResolver
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly TenantResolveOptions _options;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
public TenantResolver(IOptions<TenantResolveOptions> options, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_options = options.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析租户Id或名称
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task<TenantResolveResult> ResolveTenantIdOrNameAsync()
|
||||||
|
{
|
||||||
|
TenantResolveResult? result = new TenantResolveResult();
|
||||||
|
|
||||||
|
using (IServiceScope? serviceScope = _serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
TenantResolveContext? context = new TenantResolveContext(serviceScope.ServiceProvider);
|
||||||
|
|
||||||
|
foreach (ITenantResolveContributor tenantResolver in _options.TenantResolvers)
|
||||||
|
{
|
||||||
|
await tenantResolver.ResolveAsync(context);
|
||||||
|
|
||||||
|
result.AppliedResolvers.Add(tenantResolver.Name);
|
||||||
|
|
||||||
|
if (context.HasResolvedTenantOrHost())
|
||||||
|
{
|
||||||
|
result.TenantIdOrName = context.TenantIdOrName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,4 +6,9 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||||
|
<ProjectReference Include="..\Yi.Framework.Data\Yi.Framework.Data.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,7 +1,20 @@
|
|||||||
namespace Yi.Framework.MultiTenancy
|
using Microsoft.AspNetCore.Builder;
|
||||||
{
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
public class YiFrameworkMultiTenancyModule
|
using StartupModules;
|
||||||
{
|
using Yi.Framework.MultiTenancy.Extensions;
|
||||||
|
|
||||||
|
namespace Yi.Framework.MultiTenancy
|
||||||
|
{
|
||||||
|
public class YiFrameworkMultiTenancyModule : IStartupModule
|
||||||
|
{
|
||||||
|
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
|
||||||
|
{
|
||||||
|
services.AddCurrentTenant();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using StartupModules;
|
using StartupModules;
|
||||||
|
using Yi.Framework.Core.Attributes;
|
||||||
|
using Yi.Framework.Core;
|
||||||
|
using Yi.Framework.Ddd;
|
||||||
|
|
||||||
namespace Yi.Framework.FileManager
|
namespace Yi.Framework.FileManager
|
||||||
{
|
{
|
||||||
|
[DependsOn(
|
||||||
|
typeof(YiFrameworkDddModule)
|
||||||
|
)]
|
||||||
public class YiFrameworkFileManagerModule : IStartupModule
|
public class YiFrameworkFileManagerModule : IStartupModule
|
||||||
{
|
{
|
||||||
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using StartupModules;
|
using StartupModules;
|
||||||
using Yi.Framework.Core;
|
|
||||||
using Yi.Framework.Core.Attributes;
|
using Yi.Framework.Core.Attributes;
|
||||||
|
using Yi.Framework.Ddd;
|
||||||
|
|
||||||
namespace Yi.Framework.OperLogManager
|
namespace Yi.Framework.OperLogManager
|
||||||
{
|
{
|
||||||
[DependsOn(typeof(YiFrameworkCoreModule))]
|
[DependsOn(
|
||||||
|
typeof(YiFrameworkDddModule)
|
||||||
|
)]
|
||||||
public class YiFrameworkOperLogManagerModule : IStartupModule
|
public class YiFrameworkOperLogManagerModule : IStartupModule
|
||||||
{
|
{
|
||||||
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
||||||
|
|||||||
Reference in New Issue
Block a user