【愚公系列】2022年03月 .NET架构班 015-ABP vNext 多租户模块

举报
愚公搬代码 发表于 2022/03/07 02:00:59 2022/03/07
【摘要】 一、租户模块 1.租户和多租户多租户定义:多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用户间数据的隔离性。简单讲:在一台服务器上运行单个应用实例,它为多个租户(客户)提供服务。从定义中我们可以理解:多租户是一种架构,目的是为了让多用户环境下使用同一套程序,且保证用户间数据隔离。...

一、租户模块

1.租户和多租户

多租户定义:多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用户间数据的隔离性。简单讲:在一台服务器上运行单个应用实例,它为多个租户(客户)提供服务。从定义中我们可以理解:多租户是一种架构,目的是为了让多用户环境下使用同一套程序,且保证用户间数据隔离。那么重点就很浅显易懂了,多租户的重点就是同一套程序下实现多用户数据的隔离。

2. 独立数据库

这是第一种方案,即一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本较高。

3. 共享数据库,独立 Schema

这是第二种方案,即多个或所有租户共享Database,但是每个租户一个Schema(也可叫做一个user)。底层库比如是:DB2、ORACLE等,一个数据库下可以有多个SCHEMA

4. 共享数据库,共享 Schema,共享数据表

这是第三种方案,即租户共享同一个Database、同一个Schema,但在表中增加TenantID多租户的数据字段。这是共享程度最高、隔离级别最低的模式。即每插入一条数据时都需要有一个客户的标识。这样才能在同一张表中区分出不同客户的数据。

5.租户模块的源码

下载地址:

https://github.com/abpframework/abp/tree/dev/modules/TenantManagement

二、集成权限模块

1.EBusiness.Domain.Shared集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.Domain.Shared

2、然后在EBusinessDomainSharedModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementDomainSharedModule)
        )]
 public class EBusinessDomainSharedModule : AbpModule
 {}

2.EBusiness.Domain集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.Domain

2、然后在EBusinessDomainModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementDomainModule)
        )]
    public class EBusinessDomainSharedModule : AbpModule

 {}

3.EBusiness.EntityFrameworkCore集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.EntityFrameworkCore

2、然后在EBusinessEntityFrameworkCoreModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementEntityFrameworkCoreModule)
        )]
    public class EBusinessEntityFrameworkCoreModule: AbpModule

 {}

3、然后在EBusinessDbContext类上实现ITenantManagementDbContext上下文

 public DbSet<TenantGrant> TenantGrants { get; }

4、然后在EBusinessDbContext类上添加

 [ReplaceDbContext(typeof(ITenantManagementDbContext))]
    [ConnectionStringName("Default")]
    public class EBusinessDbContext : 
        AbpDbContext<EBusinessDbContext>,
        ITenantManagementDbContext
    {}

5、然后在OnModelCreating方法中添加

 protected override void OnModelCreating(ModelBuilder builder)
 {
 	base.OnModelCreating(builder);

    /* Include modules to your migration db context */
    .....          
    builder.ConfigureTenantManagement();
    .....
 }

7、最后启动YDT.EBusiness.DbMigrator迁移项目,生成租户表
在这里插入图片描述

4.EBusiness.Application.Contracts集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.Application.Contracts

2、然后在EBusinessApplicationContractsModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementApplicationContractsModule)
        )]
 public class EBusinessApplicationContractsModule: AbpModule
 {}

5.EBusiness.Application集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.Application.Contracts

2、然后在EBusinessApplicationModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementApplicationModule)
        )]
 public class EBusinessApplicationContractsModule: AbpModule
 {}

6.EBusiness.HttpApi集成多租户模块

1、先在项目中通过Nuget下载

Volo.Abp.TenantManagement.Application.Contracts

2、然后在EBusinessHttpApiModule文件上增加

[DependsOn(
        typeof(AbpTenantManagementHttpApiModule)
 )]
 public class EBusinessHttpApiModule: AbpModule
 {}

7.EBusinessHttpApiHostModule使用多租户

if (MultiTenancyConsts.IsEnabled)
{
    app.UseMultiTenancy();
}

三、继承租户模块

1、先在EBusiness.Domain模块中通过Nuget引入

 Volo.Abp.MultiTenancy

2、然后在EBusiness.Domain模块中Product类上添加IMultiTenant接口

public class Product : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
    public Guid? TenantId { get; protected set; } // 租户Id
    public string ProductCode { set; get; }    //商品编码
    public string ProductUrl { set; get; }         // 商品主图
    public string ProductTitle { set; get; }       //商品标题
    public string ProductDescription { set; get; }     // 图文描述
    public decimal ProductVirtualprice { set; get; } //商品虚拟价格
    public decimal ProductPrice { set; get; }       //价格
    public int ProductSort { set; get; }    //商品序号
    public int ProductSold { set; get; }        //已售件数
    public int ProductStock { set; get; }       //商品库存
    public string ProductStatus { set; get; } // 商品状态
    ....
 }

3、然后运行EBusiness.DbMigrator项目生成商品多租户表,如下图所示
在这里插入图片描述
4、然后运行项目

四、使用租户模块

1.租户创建

1、Tenant(租户)接口
在这里插入图片描述
2、使用post接口添加租户信息
在这里插入图片描述

2.租户转换(切换)存储

1、获取租户
在这里插入图片描述

2、TenantSwitch接口
在这里插入图片描述

/// <summary>
/// 租户转换服务
/// </summary>
public class TenantSwitchAppService : EBusinessAppService, ITenantSwitchAppService
{
    public ITenantStore TenantStore { set; get; }

    public IHttpContextAccessor httpContextAccessor { get; set; }
    public void SwitchTenant(TenantSwitchInputDto tenantSwitchInputDto)
    {
        var guid = CurrentTenant.Id;
        Guid? tenantId = null;
        if (!tenantSwitchInputDto.Name.IsNullOrEmpty())
        {
            var tenant = TenantStore.Find(tenantSwitchInputDto.Name);
            if (tenant == null)
            {
                throw new BusinessException($"{tenantSwitchInputDto.Name},租户不存在");
            }

            if (!tenant.IsActive)
            {
                throw new BusinessException($"{tenantSwitchInputDto.Name},租户未激活");
            }

            tenantId = tenant.Id;
        }

        MultiTenancyCookieHelper.SetTenantCookie(httpContextAccessor.HttpContext, tenantId, TenantResolverConsts.DefaultTenantKey);
    }
}
public static class MultiTenancyCookieHelper
{
    public static void SetTenantCookie(
        HttpContext context,
        Guid? tenantId,
        string tenantKey)
    {
        if (tenantId != null)
        {
            context.Response.Cookies.Append(
                tenantKey,
                tenantId.ToString(),
                new CookieOptions
                {
                    Path = "/",
                    HttpOnly = false,
                    Expires = DateTimeOffset.Now.AddYears(10)
                }
            );
        }
        else
        {
            context.Response.Cookies.Delete(tenantKey);
        }
    }
}

3、在post租户转换转换租户,存储到cookie
在这里插入图片描述

3.租户取值

1、在EBusiness.Application模块中ProductService类中创建商品使用ICurrentTenant获取租户信息

public class ProductService : EBusinessAppService, IProductService
{
    public void Create(CreateProductDto createProductDto)
    {
        var tenantId = CurrentTenant.Id;
        ....
    }
}   

4.自定义多租户解析

/// <summary>
/// 多租户 redis自定义解析
/// </summary>
public class RedisTenantResolveContributor : TenantResolveContributorBase
{
    public override string Name => "redis";

    public override Task ResolveAsync(ITenantResolveContext context)
    {
        // 1、获取tanentKey
        string tanentKey = TenantResolverConsts.DefaultTenantKey;

        // 2、从redis取值

        // 3、把值设置到上下文
        context.TenantIdOrName = "";

        return Task.CompletedTask;
    }
}

在EBusinessApplicationModule中配置

Configure<AbpTenantResolveOptions>(options =>
{
    options.TenantResolvers.Add(new RedisTenantResolveContributor());
});

五、租户模模块原理

1.多租户管理原理

条件

1、Volo.Abp.MultiTenancy模块

接口

1、TenantDefinition

2、TenantDefinitionProvider

3、TenantDefinitionManager

说明

1、TenantDefinition执行定义

2、TenantDefinitionProvider提供多租户。

3、TenantDefinitionManager 核心执行

2.多租户转换存储原理

条件

1YDT.EBusiness.Application模块

2、Volo.Abp.TenantManagement.Domain模块

接口

1、TenantSwitchAppService

2、TenantManager

3、TenantManagementProvider

4、ITenantGrantRepository

说明

1、TenantSwitchAppService负责入口

2、TenantManager负责管理转换

3、TenantManagementProvider负责转换

4、ITenantGrantRepository负责租户取值

3.多租户取值原理

条件

1、Volo.Abp.MultiTenancy模块

2、Volo.Abp.AspNetCore.MultiTenancy模块

接口

1、MultiTenancyMiddleware

2、TenantConfigurationProvider

3、TenantResolver

4、ITenantResolveContributor

说明

1、MultiTenancyMiddleware负责从请求中获取

2、TenantConfigurationProvider负责提供多租户所有信息发

3、TenantResolver负责统一解析租户

4、ITenantResolveContributor负责具体解析租户

4.多租户EFCore原理

条件

1、Volo.Abp.EntityFrameworkCore模块

接口

1、AbpDbContext

说明

1、AbpDbContext负责从实体中过滤租户IMultiTenant接口中TenantId租户Id

在这里插入图片描述

六、租户模块其他客户端使用

1.EBusiness.Web页面访问权限模块

1、先在YDT.EBusiness.Web模块中通过Nuget引入

Volo.Abp.TenantManagement.Web

2、然后在YDT.EBusiness.Web模块中EBusinessWebModule类上添加

[DependsOn(
    ....
        typeof(AbpTenantManagementWebModule),
     ....
        )]
    public class EBusinessWebModule : AbpModule
    {}

2.OA系统调用租户模块

1、先在项目中通过Nuget下载

YDT.EBusiness.HttpApi.Client

2、然后在YDT.OA文件上增加

 [DependsOn(
	typeof(AbpTenantManagementHttpApiClientModule)
 )]
 public class OAModule: AbpModule
 {}

七、租户数据库使用

1.租户数据库添加操作

1、使用数据库脚本创建ydt_ebusiness_14数据库
在这里插入图片描述
2、添加租户数据库字符串
在这里插入图片描述
在这里插入图片描述

2.租户数据库切换原理

条件

1、Volo.Abp.EntityFrameworkCore模块

2、Volo.Abp.MultiTenancy模块

接口

1、DbContextOptionsFactory

2、MultiTenantConnectionStringResolver

说明

1、DbContextOptionsFactory负责动态获取数据库连接

2、MultiTenantConnectionStringResolver负责解析租户数据库字符串
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。