FBW.DotNet.AspNetCore
1.0.7
dotnet add package FBW.DotNet.AspNetCore --version 1.0.7
NuGet\Install-Package FBW.DotNet.AspNetCore -Version 1.0.7
<PackageReference Include="FBW.DotNet.AspNetCore" Version="1.0.7" />
<PackageVersion Include="FBW.DotNet.AspNetCore" Version="1.0.7" />
<PackageReference Include="FBW.DotNet.AspNetCore" />
paket add FBW.DotNet.AspNetCore --version 1.0.7
#r "nuget: FBW.DotNet.AspNetCore, 1.0.7"
#:package FBW.DotNet.AspNetCore@1.0.7
#addin nuget:?package=FBW.DotNet.AspNetCore&version=1.0.7
#tool nuget:?package=FBW.DotNet.AspNetCore&version=1.0.7
FBW.DotNet.AspNetCore
ASP.NET Core扩展包,目前支持.NET3.1,.NET5,.NET6,.NET7,.NET8,.NET9
如何使用
1、安装FBW.DotNet.AspNetCore
依赖。
Cmd install:
dotnet add package FBW.DotNet.AspNetCore
2、在Startup.cs
中配置
//Mvc相关配置
builder.Services.AddDotNetDefaultMvc();
//Identity相关配置
builder.Services.AddDotNetIdentityServer(options => {
options.PrivateKey = builder.Configuration["SystemConfig:PrivateKey"];
}).AddResourceOwnerValidator<ResourceOwnerPasswordValidator>();
//数据库配置
builder.Services.AddDotNetDbContextPool<IdentityContext>(options =>
{
options.ConfigureDbContext = op =>
{
op.UseNpgsql(builder.Configuration["SystemConfig:DBConnectionString"],
//看实际情况指定迁移程序集
b => b.MigrationsAssembly("DotNet.AspNetCore.WebApi"))
.UseSnakeCaseNamingConvention()
#if !DEBUG
.EnableSensitiveDataLogging()
#endif
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddSerilog()));
//.EnableSensitiveDataLogging();
// 配置日志输出
//op.LogTo(Console.WriteLine);
};
options.UseRepository<IdentityContext>();
options.UseUnitOfWork<IdentityContext>();
options.UseDotNetRedisCache(builder.Configuration.GetSection("RedisConfig").Get<RedisOptions>(), 100,100);
});
#region 多租户
builder.Services.AddDotNetTenantDbContext<TenantDbContext>(options =>
{
var provider = builder.Configuration.GetValue("Provider", "PostgreSql");
var tenantDBConfig = builder.Configuration.GetSection("SystemConfig:MultiTenantDBConfig")
.Get<List<MultiTenantDBConfig>>()?.FirstOrDefault(t => t.DBProvider.ToString() == provider);
options.ConfigureDbContext = op =>
{
op.UseNpgsql(builder.Configuration["SystemConfig:DBConnectionString"])
.UseSnakeCaseNamingConvention()
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddSimpleConsole()));
};
options.TenantDBConfig = tenantDBConfig;
options.UseRepository<TenantDbContext>();
options.AddDatabaseProvider<PostgreSqlProvider>();
options.AddDatabaseProvider<SqlServerProvider>();
options.AddDatabaseProvider<MySqlProvider>();
});
builder.Services.UseMultiTenancy();
#endregion
//jwt相关配置
builder.Services.AddDotNetJwtBearerAuthentication(builder.Configuration["SystemConfig:PublicKey"],builder.Configuration["SystemConfig:ValidIssuer"]);
//SwaggerDoc配置
builder.Services.Configure<SwaggerConfig>(builder.Configuration.GetSection("SwaggerConfig"));
builder.Services.AddSwaggerDoc(builder.Configuration.GetSection("SwaggerConfig").Get<SwaggerConfig>());
var app = builder.Build();
app.UseDotNetDefaultWebApi();
app.UseSwaggerUI(builder.Configuration.GetSection("SwaggerConfig").Get<SwaggerConfig>());
app.UseIdentityServer();
//初始化多租户数据库
app.Services.InitTenantDatabase<TenantDbContext>();
- 必须 你需要创建ResourceOwnerPasswordValidator继承IResourceOwnerPasswordValidator接口实现ValidateAsync方法参考下图
- 多租户支持id隔离和库隔离
- 多租户支持从token中解析TenantId字段(CurrentTokenTenantResolveContributor),请求头中解析TenantId字段(CurrentHeaderTenantResolveContributor),地址栏中解析TenantId字段(CurrentQueryTenantResolveContributor)
- 扩展解析策略继承TenantResolveContributorBase抽象类型 ,以单例模式注入租户访问器ICurrentTenantAccessor
- 安装合适版本的Microsoft.EntityFrameworkCore.Design,在web程序目录创建MyMigrationsScaffolder,MyMigrationDesignTimeServices
- 必须修改DotNet.AspNetCore.WebApi.csproj的配置 参考如下图
- MyMigrationsScaffolder,MyMigrationDesignTimeServices代码参考
//重写GetDirectory 不进行深度检查
public class MyMigrationsScaffolder: MigrationsScaffolder
{
private readonly Type _contextType;
public MyMigrationsScaffolder(MigrationsScaffolderDependencies dependencies) : base(dependencies)
{
_contextType = dependencies.CurrentContext.Context.GetType();
}
protected override string GetDirectory(string projectDir, string? siblingFileName, string subnamespace)
{
var defaultDirectory = Path.Combine(projectDir, Path.Combine(subnamespace.Split('.')));
if (siblingFileName != null)
{
if (!siblingFileName.StartsWith(_contextType.Name + "ModelSnapshot."))
{
var siblingPath = TryGetProjectFile(projectDir, siblingFileName);
if (siblingPath != null)
{
var lastDirectory = Path.GetDirectoryName(siblingPath)!;
if (!defaultDirectory.Equals(lastDirectory, StringComparison.OrdinalIgnoreCase))
{
Dependencies.OperationReporter.WriteVerbose(DesignStrings.ReusingNamespace(siblingFileName));
return lastDirectory;
}
}
}
}
return defaultDirectory;
}
/// <summary>
/// https://docs.microsoft.com/en-us/ef/core/cli/services
/// </summary>
public class MyMigrationDesignTimeServices: IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IMigrationsScaffolder, MyMigrationsScaffolder>();
}
}
- PostgreSqlProvider/SqlServerProvider 代码参考 按需扩展支持不同的数据库*
3、 appsettings.json配置文件实例:
{
//接口文档配置
"SwaggerConfig": {
"Title": "DotNet.Admin.Web",
"Version": "v1",
"Description": "DotNet.Admin.Web",
"Name": "DotNet",
"Email": "2231030106@qq.com",
"ProxyRoutes": {
//"localhost": "http://127.0.0.1:6033/IdentityServer"
},
"RoutePrefix": "help",
"IsAdminHelpUI": true,
"AdminSecret": "admin",
"IsSwaggerBasicAuth": false
},
//redis 配置 (启用redis时配置)
"RedisConfig": {
"Connection": "127.0.0.1:6379,password=123456",
"KeyPrefix": "dotnetadminweb",
"DataProtecteKey": "dataprotectionkeys",
"IsSentinel": false, // 是否哨兵模式
"SentinelConfig": {
"EndPoints": [ // 哨兵端口
// "10.10.0.124:26380"
],
"Password": "123456",
"SentinelPassword": "123456",
"ServiceName": "dotnetadminweb",
"DefaultDatabase": 0,
"Password": "123456",
"SentinelPassword": null,
"ConnectionSelectionStrategy": "RoundRobin" //LeastLoaded RoundRobin
}
},
//系统配置
"SystemConfig": {
"ValidIssuer": "https://localhost:44354",
"DatabaseVisitLogSleep": 10000,//系统日志入库时间
"DBConnectionString": "Host=127.0.0.1;Username=postgres;Password=123456;Database=DotNet_Template",
//多租户模式下同时支持不同的数据库集合,仅开发迁移多租户不同数据库时需要配置
"MultiTenantDBConfig": [
{
"DBProvider": "PostgreSql",
"DBConnectionString": "Host=127.0.0.1;Username=postgres;Password=123456;Database=DotNet_Template_470786554998853"
},
{
"DBProvider": "SqlServer",
"DBConnectionString": "Data Source=.;Initial Catalog=DotNet_Template_470786554998853;User Id=sa;Password=123456;Encrypt=True;TrustServerCertificate=True"
}
],
"PublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiQPMKq+BQIhoImH30v8FH02x8S8Bz6+ROwzidBEk8C2BidnnMFs2OeXQeHRW7HSJRAhTVTBwhWoJ+3G/C2L6FiMLYPgaKpWsacqZPkbcgpHKfQLJn1weXeZqLNeZKi+aebOX27JOt9cph/YVb5hBTgVzl5q7yASOEg9+wV/y1d8Jq4EAlzXdAux+JRgMGQgj8CSPSSY1z2PO4iZProdgFa/dto8AlVRabVCTx6BoCnMrImy2XRHdF0Ue0eY5mtAAsnLudjKqm8AUopMOivNCLVI5eXzMIoMmpa0bUj7IluoushYVLY0dw7flyKldiDbyvi4w/jrxHRruNMb11fNEFQIDAQAB",
"PrivateKey": "MIIEowIBAAKCAQEAiQPMKq+BQIhoImH30v8FH02x8S8Bz6+ROwzidBEk8C2BidnnMFs2OeXQeHRW7HSJRAhTVTBwhWoJ+3G/C2L6FiMLYPgaKpWsacqZPkbcgpHKfQLJn1weXeZqLNeZKi+aebOX27JOt9cph/YVb5hBTgVzl5q7yASOEg9+wV/y1d8Jq4EAlzXdAux+JRgMGQgj8CSPSSY1z2PO4iZProdgFa/dto8AlVRabVCTx6BoCnMrImy2XRHdF0Ue0eY5mtAAsnLudjKqm8AUopMOivNCLVI5eXzMIoMmpa0bUj7IluoushYVLY0dw7flyKldiDbyvi4w/jrxHRruNMb11fNEFQIDAQABAoIBADoBSpETpfONDBDqSsGfxypeeSOzE+A54pEOPlyG2Y14pmuWvYJCSy2ttlkYX6hRGb+cirL5A9nnb3xsxkVqzJdMlMejoWg/3zMWW1P7KeV5FTFhWbxGgnCcWHzNdYFfj9VQC80tqpe31lRCAQcyfQsr0ajwD+l4zDCnMLFrDmIuICDFz29wMQC72t8TPCE4dykw8vr5LnKf3aJyh5ScrsNyry73Oiq2X48xadZ2Dh4TW9v5DgBDTiOlsWmXaZbNg8nlJh6MjMTbe7CO9w3ge95liz5XE/CrhR5RWJmiOY8MudvIEov1CQlVMUI11RG8mRKV5qs0Ma+5E2QEMtPWzEECgYEAzc1NxqDoqO9IgGOWRheT2i6vOJEsaeeN4u/E9bm0nYDtsLS9Dg1liSJkze2nTqpEAA1iFt79n3M0fD8CXDWcleGxF7ZeDM0xuN91FAoY4XkZFZaEi8hlsOmZ6A7qusgQQi19Win50CSdgp1Snc7Y0UBXLnvjMZJ8CjQQItL9hhECgYEAqm9IxO9pm+OdrwYD/ZpKypDzm2w7EqZi7LD4J8d63H0t/tIO1Zrxy5qKQOu8XMbkwQjVykPyZJHOd+8ICrKFbfn7xjxqPvW9h809/9jfYY3RLMhKtaDJ7ktwJxVtGmjO+PEft4RGoLmEfbrTSnarasBY99njhKNG8FtTc75cicUCgYEAwdGdcvhtxVP9SvT/PKnN1Ahteu+2DVNG3DgFnYo0oLUgpW/CMO7K9jjPCOXN0JcoDYiNHY8K+tUL1AufVGolOz7fgr58mr/RGRRR9fqAbjCXQC6OS/sCUnfeO594z0nFjh27VWP84lrpgG5btUVuCrv2n0+Lq08SxKU9oR5mJ5ECgYBnPEs2xtIQlBoCV0F5jsj41D5LCY7qqBBJ0JQv/DumbMi8jl5f8p+9tVlDI8eP5wXPC1v8TZX4Zv1KVmZnnGUIDaD9HcE5a76nEKIaZDJCtBVc6+GdDMzj45wGgIr6sTuVPPD6R0xEtLrVMaIke6cvXV1GnBudTw18L8Vn2YnSBQKBgG/NxXjh+urIa+qsIzNHbrTCt+qGsix8z1f7s1OwTlVksFW3otaNK2hIDMlslUgRnVzjZfPyzKME/EuA/WjqAn/ZxqDR1TYvgxil8EaBn9jTEL7LO06ggCuh1dnmPrzC06no5E6Gj4m+6tknO5K5/NU/2HqQnaR6IB514ut7URba"
}
}
4、Efcore迁移 需要安装 Microsoft.EntityFrameworkCore.Design,Microsoft.EntityFrameworkCore.Tools
add-migration Ids4Config001 -c IdentityContext -o Migrations/Ids4Config
成功示例:
5、迁移多租户上下文
//Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\SqlServer -Args "--provider SqlServer"
//Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\MySql -Args "--provider MySql"
Add-Migration InitialCreate -Context TenantDbContext -OutputDir Migrations\PostgreSql -Args "--provider PostgreSql"
//update-database -Args "--provider MySql"
//update-database -Args "--provider SqlServer"
update-database -Args "--provider PostgreSql"
成功示例:
6、运行项目
运行成功打开swagger
自动生成数据库
需要配置库隔离的租户连接字符串 支持pgsql,sqlserver,mysql
在重新启动程序迁移多租户数据库
至此基本的配置使用完成
7、DotNetDbContext<> 自定义的DbContext继承DotNetDbContext<> 内置实现了软删除(IDeleteFilter)和 多租户(IMultiTenant)的启用和禁用,但需要继承相关的Domain接口,提供了一些审计 字段的实体定义,数据库表的实体必须继承实体接口标识(IEntity)如下图:
更多用法参考文档
.docx)
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp3.1 is compatible. |
-
.NETCoreApp 3.1
- AutoMapper (>= 12.0.1)
- AutoMapper.Extensions.Microsoft.DependencyInjection (>= 12.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 3.1.32)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 5.0.17)
- Microsoft.EntityFrameworkCore (>= 5.0.17)
- Microsoft.EntityFrameworkCore.SqlServer (>= 5.0.17)
- Microsoft.Extensions.DependencyInjection (>= 5.0.2)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 5.0.0)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 5.0.0)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
-
net5.0
- AutoMapper (>= 12.0.1)
- AutoMapper.Extensions.Microsoft.DependencyInjection (>= 12.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 5.0.17)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 5.0.17)
- Microsoft.EntityFrameworkCore (>= 5.0.17)
- Microsoft.EntityFrameworkCore.SqlServer (>= 5.0.17)
- Microsoft.Extensions.DependencyInjection (>= 5.0.2)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 5.0.0)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 5.0.0)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
-
net6.0
- Asp.Versioning.Mvc.ApiExplorer (>= 6.4.0)
- AutoMapper (>= 13.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 6.0.30)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 6.0.31)
- Microsoft.EntityFrameworkCore (>= 7.0.19)
- Microsoft.EntityFrameworkCore.SqlServer (>= 7.0.19)
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 7.0.18)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 7.0.0)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
-
net7.0
- Asp.Versioning.Mvc.ApiExplorer (>= 7.1.0)
- AutoMapper (>= 13.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 7.0.19)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 7.0.20)
- Microsoft.EntityFrameworkCore (>= 7.0.19)
- Microsoft.EntityFrameworkCore.SqlServer (>= 7.0.19)
- Microsoft.Extensions.DependencyInjection (>= 7.0.0)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 7.0.18)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 7.0.0)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
-
net8.0
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- AutoMapper (>= 13.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.6)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 8.0.6)
- Microsoft.EntityFrameworkCore (>= 8.0.6)
- Microsoft.EntityFrameworkCore.SqlServer (>= 8.0.6)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 8.0.4)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 8.0.2)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
-
net9.0
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- AutoMapper (>= 13.0.1)
- FastMember (>= 1.5.0)
- IdentityServer4 (>= 4.1.2)
- IGeekFan.AspNetCore.Knife4jUI (>= 0.0.16)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 9.0.8)
- Microsoft.AspNetCore.DataProtection.StackExchangeRedis (>= 9.0.8)
- Microsoft.EntityFrameworkCore (>= 9.0.8)
- Microsoft.EntityFrameworkCore.SqlServer (>= 9.0.8)
- Microsoft.Extensions.DependencyInjection (>= 9.0.8)
- Namotion.Reflection (>= 3.4.2)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 9.0.4)
- OnceMi.AspNetCore.IdGenerator (>= 1.0.6)
- Polly (>= 8.6.2)
- Pomelo.EntityFrameworkCore.MySql (>= 9.0.0)
- RazorEngine.NetCore (>= 3.1.0)
- StackExchange.Redis.Extensions.Core (>= 10.2.0)
- StackExchange.Redis.Extensions.System.Text.Json (>= 10.2.0)
- Swashbuckle.AspNetCore.Annotations (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerGen (>= 6.6.2)
- Swashbuckle.AspNetCore.SwaggerUI (>= 6.6.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.