commit
a963de4aca
279 changed files with 23906 additions and 0 deletions
@ -0,0 +1,13 @@ |
|||
{ |
|||
"version": 1, |
|||
"isRoot": true, |
|||
"tools": { |
|||
"dotnet-ef": { |
|||
"version": "9.0.4", |
|||
"commands": [ |
|||
"dotnet-ef" |
|||
], |
|||
"rollForward": false |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,55 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio Version 17 |
|||
VisualStudioVersion = 17.0.31903.59 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C0426B52-8F01-41DE-966C-ADC8DD078638}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellularManagement.WebAPI", "src\CellularManagement.WebAPI\CellularManagement.WebAPI.csproj", "{0E228A93-4B80-450E-BDBB-BAF576E6FC73}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellularManagement.Presentation", "src\CellularManagement.Presentation\CellularManagement.Presentation.csproj", "{8BC4CD0B-54B9-41BA-B180-964E27B0A444}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellularManagement.Domain", "src\CellularManagement.Domain\CellularManagement.Domain.csproj", "{95F5B3F8-8293-43D0-98CF-88A9A224D20E}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellularManagement.Application", "src\CellularManagement.Application\CellularManagement.Application.csproj", "{FE169440-2554-4810-97D6-CC44808AAA56}" |
|||
EndProject |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CellularManagement.Infrastructure", "src\CellularManagement.Infrastructure\CellularManagement.Infrastructure.csproj", "{6CF192C7-060B-4328-B9F4-B05BD7401232}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{0E228A93-4B80-450E-BDBB-BAF576E6FC73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{0E228A93-4B80-450E-BDBB-BAF576E6FC73}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{0E228A93-4B80-450E-BDBB-BAF576E6FC73}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{0E228A93-4B80-450E-BDBB-BAF576E6FC73}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{8BC4CD0B-54B9-41BA-B180-964E27B0A444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{8BC4CD0B-54B9-41BA-B180-964E27B0A444}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{8BC4CD0B-54B9-41BA-B180-964E27B0A444}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{8BC4CD0B-54B9-41BA-B180-964E27B0A444}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{95F5B3F8-8293-43D0-98CF-88A9A224D20E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{95F5B3F8-8293-43D0-98CF-88A9A224D20E}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{95F5B3F8-8293-43D0-98CF-88A9A224D20E}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{95F5B3F8-8293-43D0-98CF-88A9A224D20E}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{FE169440-2554-4810-97D6-CC44808AAA56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{FE169440-2554-4810-97D6-CC44808AAA56}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{FE169440-2554-4810-97D6-CC44808AAA56}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{FE169440-2554-4810-97D6-CC44808AAA56}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
{6CF192C7-060B-4328-B9F4-B05BD7401232}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{6CF192C7-060B-4328-B9F4-B05BD7401232}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{6CF192C7-060B-4328-B9F4-B05BD7401232}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{6CF192C7-060B-4328-B9F4-B05BD7401232}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(NestedProjects) = preSolution |
|||
{0E228A93-4B80-450E-BDBB-BAF576E6FC73} = {C0426B52-8F01-41DE-966C-ADC8DD078638} |
|||
{8BC4CD0B-54B9-41BA-B180-964E27B0A444} = {C0426B52-8F01-41DE-966C-ADC8DD078638} |
|||
{95F5B3F8-8293-43D0-98CF-88A9A224D20E} = {C0426B52-8F01-41DE-966C-ADC8DD078638} |
|||
{FE169440-2554-4810-97D6-CC44808AAA56} = {C0426B52-8F01-41DE-966C-ADC8DD078638} |
|||
{6CF192C7-060B-4328-B9F4-B05BD7401232} = {C0426B52-8F01-41DE-966C-ADC8DD078638} |
|||
EndGlobalSection |
|||
EndGlobal |
@ -0,0 +1,17 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\CellularManagement.Domain\CellularManagement.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,19 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace CellularManagement.Application; |
|||
|
|||
/// <summary>
|
|||
/// 应用层依赖注入扩展
|
|||
/// </summary>
|
|||
public static class DependencyInjection |
|||
{ |
|||
/// <summary>
|
|||
/// 添加应用层服务
|
|||
/// </summary>
|
|||
/// <param name="services">服务集合</param>
|
|||
/// <returns>服务集合</returns>
|
|||
public static IServiceCollection AddApplicationServices(this IServiceCollection services) |
|||
{ |
|||
return services; |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
|
|||
namespace CellularManagement.Application.Services; |
|||
|
|||
/// <summary>
|
|||
/// 缓存服务接口
|
|||
/// </summary>
|
|||
public interface ICacheService |
|||
{ |
|||
/// <summary>
|
|||
/// 获取缓存项
|
|||
/// </summary>
|
|||
/// <typeparam name="T">缓存项类型</typeparam>
|
|||
/// <param name="key">缓存键</param>
|
|||
/// <returns>缓存项</returns>
|
|||
T? Get<T>(string key); |
|||
|
|||
/// <summary>
|
|||
/// 设置缓存项
|
|||
/// </summary>
|
|||
/// <typeparam name="T">缓存项类型</typeparam>
|
|||
/// <param name="key">缓存键</param>
|
|||
/// <param name="value">缓存值</param>
|
|||
/// <param name="options">缓存选项</param>
|
|||
void Set<T>(string key, T value, MemoryCacheEntryOptions? options = null); |
|||
|
|||
/// <summary>
|
|||
/// 尝试添加缓存项
|
|||
/// </summary>
|
|||
/// <typeparam name="T">缓存项类型</typeparam>
|
|||
/// <param name="key">缓存键</param>
|
|||
/// <param name="value">缓存值</param>
|
|||
/// <param name="options">缓存选项</param>
|
|||
/// <returns>是否添加成功</returns>
|
|||
bool TryAdd<T>(string key, T value, MemoryCacheEntryOptions options); |
|||
|
|||
/// <summary>
|
|||
/// 移除缓存项
|
|||
/// </summary>
|
|||
/// <param name="key">缓存键</param>
|
|||
void Remove(string key); |
|||
|
|||
/// <summary>
|
|||
/// 尝试获取缓存项
|
|||
/// </summary>
|
|||
/// <typeparam name="T">缓存项类型</typeparam>
|
|||
/// <param name="key">缓存键</param>
|
|||
/// <param name="value">缓存值</param>
|
|||
/// <returns>是否获取成功</returns>
|
|||
bool TryGetValue<T>(string key, out T? value); |
|||
} |
@ -0,0 +1,120 @@ |
|||
using System.Security.Claims; |
|||
|
|||
namespace CellularManagement.Application.Services; |
|||
|
|||
/// <summary>
|
|||
/// JWT 令牌提供者接口
|
|||
/// 用于生成和验证 JWT 令牌
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 提供令牌生成功能
|
|||
/// 2. 支持刷新令牌
|
|||
/// 3. 支持自定义声明
|
|||
/// 4. 支持令牌验证
|
|||
/// </remarks>
|
|||
public interface IJwtProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 生成访问令牌
|
|||
/// </summary>
|
|||
/// <param name="claims">用户声明</param>
|
|||
/// <returns>生成的访问令牌</returns>
|
|||
string GenerateAccessToken(IEnumerable<Claim> claims); |
|||
|
|||
/// <summary>
|
|||
/// 生成刷新令牌
|
|||
/// </summary>
|
|||
/// <param name="claims">用户声明</param>
|
|||
/// <returns>生成的刷新令牌</returns>
|
|||
string GenerateRefreshToken(IEnumerable<Claim> claims); |
|||
|
|||
/// <summary>
|
|||
/// 验证令牌
|
|||
/// </summary>
|
|||
/// <param name="token">要验证的令牌</param>
|
|||
/// <returns>验证结果</returns>
|
|||
bool ValidateToken(string token); |
|||
|
|||
/// <summary>
|
|||
/// 撤销令牌
|
|||
/// </summary>
|
|||
/// <param name="token">要撤销的令牌</param>
|
|||
void RevokeToken(string token); |
|||
|
|||
/// <summary>
|
|||
/// 将令牌添加到黑名单
|
|||
/// </summary>
|
|||
/// <param name="token">要添加到黑名单的令牌</param>
|
|||
void AddToBlacklist(string token); |
|||
|
|||
/// <summary>
|
|||
/// 从令牌中获取声明
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>声明集合</returns>
|
|||
IEnumerable<Claim> GetClaimsFromToken(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌过期时间
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>过期时间</returns>
|
|||
DateTime GetTokenExpiration(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌颁发时间
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>颁发时间</returns>
|
|||
DateTime GetTokenIssuedAt(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌主题
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>主题</returns>
|
|||
string? GetTokenSubject(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌颁发者
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>颁发者</returns>
|
|||
string? GetTokenIssuer(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌受众
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>受众</returns>
|
|||
string? GetTokenAudience(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌算法
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>算法</returns>
|
|||
string? GetTokenAlgorithm(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌类型
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>类型</returns>
|
|||
string? GetTokenType(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取令牌ID
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>ID</returns>
|
|||
string? GetTokenId(string token); |
|||
|
|||
/// <summary>
|
|||
/// 获取所有声明
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>声明字典</returns>
|
|||
IDictionary<string, string> GetAllClaims(string token); |
|||
} |
@ -0,0 +1,34 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace CellularManagement.Application.Services; |
|||
|
|||
/// <summary>
|
|||
/// 密钥轮换服务接口
|
|||
/// </summary>
|
|||
public interface IKeyRotationService |
|||
{ |
|||
/// <summary>
|
|||
/// 初始化密钥轮换服务
|
|||
/// </summary>
|
|||
Task InitializeAsync(); |
|||
|
|||
/// <summary>
|
|||
/// 获取当前密钥
|
|||
/// </summary>
|
|||
string GetCurrentKey(); |
|||
|
|||
/// <summary>
|
|||
/// 获取下一个密钥
|
|||
/// </summary>
|
|||
string GetNextKey(); |
|||
|
|||
/// <summary>
|
|||
/// 轮换密钥
|
|||
/// </summary>
|
|||
Task RotateKeyAsync(); |
|||
|
|||
/// <summary>
|
|||
/// 验证密钥是否需要轮换
|
|||
/// </summary>
|
|||
bool ShouldRotateKey(); |
|||
} |
@ -0,0 +1,362 @@ |
|||
{ |
|||
"runtimeTarget": { |
|||
"name": ".NETCoreApp,Version=v8.0", |
|||
"signature": "" |
|||
}, |
|||
"compilationOptions": {}, |
|||
"targets": { |
|||
".NETCoreApp,Version=v8.0": { |
|||
"CellularManagement.Application/1.0.0": { |
|||
"dependencies": { |
|||
"CellularManagement.Domain": "1.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "8.0.0" |
|||
}, |
|||
"runtime": { |
|||
"CellularManagement.Application.dll": {} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Relational": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Stores": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Abstractions": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore.Analyzers": "7.0.0", |
|||
"Microsoft.Extensions.Caching.Memory": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "8.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": {}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/8.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"assemblyVersion": "8.0.0.0", |
|||
"fileVersion": "8.0.23.53103" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { |
|||
"runtime": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"assemblyVersion": "8.0.0.0", |
|||
"fileVersion": "8.0.23.53103" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Core": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": "8.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "8.0.0" |
|||
}, |
|||
"runtime": { |
|||
"CellularManagement.Domain.dll": { |
|||
"assemblyVersion": "1.0.0", |
|||
"fileVersion": "1.0.0.0" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"libraries": { |
|||
"CellularManagement.Application/1.0.0": { |
|||
"type": "project", |
|||
"serviceable": false, |
|||
"sha512": "" |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-hFF+HOqtiNrGtO5ZxLVAFo1ksDLQWf8IHEmGRmcF9azlUWvDLZp8+W8gDyLBcGcY5m3ugEvKy/ncElxO4d0NtQ==", |
|||
"path": "microsoft.aspnetcore.cryptography.internal/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-rCQddWkUxGmObeftM0YVyFOPcXkXDEWKGCc4F1viRLEL4ojIbdKwbOYBSf5hfWDR+NO0aGq8r3a8COvNYN/bZA==", |
|||
"path": "microsoft.aspnetcore.cryptography.keyderivation/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-mtomuG24wGpvdblVQUj/JHIZ1i8oNhRNHr0V0re8fTkv15hz+AQLdtwbdd6FdINNeXiKi3kGmzZ7PE1KOyzoSg==", |
|||
"path": "microsoft.aspnetcore.identity.entityframeworkcore/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-9W+IfmAzMrp2ZpKZLhgTlWljSBM9Erldis1us61DAGi+L7Q6vilTbe1G2zDxtYO8F2H0I0Qnupdx5Cp4s2xoZw==", |
|||
"path": "microsoft.entityframeworkcore/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Pfu3Zjj5+d2Gt27oE9dpGiF/VobBB+s5ogrfI9sBsXQE1SG49RqVz5+IyeNnzhyejFrPIQsPDRMchhcojy4Hbw==", |
|||
"path": "microsoft.entityframeworkcore.abstractions/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Qkd2H+jLe37o5ku+LjT6qf7kAHY75Yfn2bBDQgqr13DTOLYpEy1Mt93KPFjaZvIu/srEcbfGGMRL7urKm5zN8Q==", |
|||
"path": "microsoft.entityframeworkcore.analyzers/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-eQiYygtR2xZ0Uy7KtiFRHpoEx/U8xNwbNRgu1pEJgSxbJLtg6tDL1y2YcIbSuIRSNEljXIIHq/apEhGm1QL70g==", |
|||
"path": "microsoft.entityframeworkcore.relational/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==", |
|||
"path": "microsoft.extensions.caching.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==", |
|||
"path": "microsoft.extensions.caching.memory/7.0.0", |
|||
"hashPath": "microsoft.extensions.caching.memory.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==", |
|||
"path": "microsoft.extensions.configuration.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/8.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==", |
|||
"path": "microsoft.extensions.dependencyinjection/8.0.0", |
|||
"hashPath": "microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", |
|||
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", |
|||
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-cq11jroq2szFcXLJ0IW5BlI7oqq3ZGCu1mXCnpJ8VIvhvpIzf30AOoWR/w3YRVdAgkYzxbUQpKGZd+oxAKQhLA==", |
|||
"path": "microsoft.extensions.identity.core/7.0.0", |
|||
"hashPath": "microsoft.extensions.identity.core.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-feaaluQbzJAMMluwSc7Rebm7IEVAD8/5GWt0dMYLE0tcc6gAsHYjBIBrPzmTstORd7k405Qo18FPF/jTfRsM0A==", |
|||
"path": "microsoft.extensions.identity.stores/7.0.0", |
|||
"hashPath": "microsoft.extensions.identity.stores.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", |
|||
"path": "microsoft.extensions.logging/7.0.0", |
|||
"hashPath": "microsoft.extensions.logging.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==", |
|||
"path": "microsoft.extensions.logging.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", |
|||
"path": "microsoft.extensions.options/7.0.0", |
|||
"hashPath": "microsoft.extensions.options.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==", |
|||
"path": "microsoft.extensions.primitives/7.0.0", |
|||
"hashPath": "microsoft.extensions.primitives.7.0.0.nupkg.sha512" |
|||
}, |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"type": "project", |
|||
"serviceable": false, |
|||
"sha512": "" |
|||
} |
|||
} |
|||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,164 @@ |
|||
{ |
|||
"format": 1, |
|||
"restore": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj": {} |
|||
}, |
|||
"projects": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"projectName": "CellularManagement.Application", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
}, |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"projectName": "CellularManagement.Domain", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": {} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess> |
|||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool> |
|||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile> |
|||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot> |
|||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\changeself\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders> |
|||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle> |
|||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.12.2</NuGetToolVersion> |
|||
</PropertyGroup> |
|||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<SourceRoot Include="C:\Users\changeself\.nuget\packages\" /> |
|||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" /> |
|||
</ItemGroup> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.0\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.0\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" /> |
|||
</ImportGroup> |
|||
</Project> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> |
|||
</ImportGroup> |
|||
</Project> |
@ -0,0 +1,4 @@ |
|||
// <autogenerated />
|
|||
using System; |
|||
using System.Reflection; |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] |
@ -0,0 +1,22 @@ |
|||
//------------------------------------------------------------------------------
|
|||
// <auto-generated>
|
|||
// This code was generated by a tool.
|
|||
//
|
|||
// Changes to this file may cause incorrect behavior and will be lost if
|
|||
// the code is regenerated.
|
|||
// </auto-generated>
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
using System; |
|||
using System.Reflection; |
|||
|
|||
[assembly: System.Reflection.AssemblyCompanyAttribute("CellularManagement.Application")] |
|||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] |
|||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] |
|||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] |
|||
[assembly: System.Reflection.AssemblyProductAttribute("CellularManagement.Application")] |
|||
[assembly: System.Reflection.AssemblyTitleAttribute("CellularManagement.Application")] |
|||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] |
|||
|
|||
// 由 MSBuild WriteCodeFragment 类生成。
|
|||
|
@ -0,0 +1 @@ |
|||
81cfc18adde389c3ed735e73d4a5a1df2880dce2491e526c9dfa723bea74f632 |
@ -0,0 +1,15 @@ |
|||
is_global = true |
|||
build_property.TargetFramework = net8.0 |
|||
build_property.TargetPlatformMinVersion = |
|||
build_property.UsingMicrosoftNETSdkWeb = |
|||
build_property.ProjectTypeGuids = |
|||
build_property.InvariantGlobalization = |
|||
build_property.PlatformNeutralAssembly = |
|||
build_property.EnforceExtendedAnalyzerRules = |
|||
build_property._SupportedPlatformList = Linux,macOS,Windows |
|||
build_property.RootNamespace = CellularManagement.Application |
|||
build_property.ProjectDir = D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\ |
|||
build_property.EnableComHosting = |
|||
build_property.EnableGeneratedComInterfaceComImportInterop = |
|||
build_property.EffectiveAnalysisLevelStyle = 8.0 |
|||
build_property.EnableCodeStyleSeverity = |
@ -0,0 +1,8 @@ |
|||
// <auto-generated/>
|
|||
global using global::System; |
|||
global using global::System.Collections.Generic; |
|||
global using global::System.IO; |
|||
global using global::System.Linq; |
|||
global using global::System.Net.Http; |
|||
global using global::System.Threading; |
|||
global using global::System.Threading.Tasks; |
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||
8dbfacc6d4b66280cdce61e7719a6ebfaf1d5c1b90fa32c02ef4a1dfb60e4950 |
@ -0,0 +1,15 @@ |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\bin\Debug\net8.0\CellularManagement.Application.deps.json |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\bin\Debug\net8.0\CellularManagement.Application.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\bin\Debug\net8.0\CellularManagement.Application.pdb |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\bin\Debug\net8.0\CellularManagement.Domain.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\bin\Debug\net8.0\CellularManagement.Domain.pdb |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.csproj.AssemblyReference.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.GeneratedMSBuildEditorConfig.editorconfig |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.AssemblyInfoInputs.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.AssemblyInfo.cs |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.csproj.CoreCompileInputs.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\Cellular.41DA911D.Up2Date |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\refint\CellularManagement.Application.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\CellularManagement.Application.pdb |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Application\obj\Debug\net8.0\ref\CellularManagement.Application.dll |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,877 @@ |
|||
{ |
|||
"version": 3, |
|||
"targets": { |
|||
"net8.0": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Relational": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Stores": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Abstractions": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore.Analyzers": "7.0.0", |
|||
"Microsoft.Extensions.Caching.Memory": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/Microsoft.EntityFrameworkCore.props": {} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/netstandard2.0/_._": {} |
|||
}, |
|||
"runtime": { |
|||
"lib/netstandard2.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/8.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Core": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"type": "project", |
|||
"framework": ".NETCoreApp,Version=v8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"bin/placeholder/CellularManagement.Domain.dll": {} |
|||
}, |
|||
"runtime": { |
|||
"bin/placeholder/CellularManagement.Domain.dll": {} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"libraries": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"sha512": "hFF+HOqtiNrGtO5ZxLVAFo1ksDLQWf8IHEmGRmcF9azlUWvDLZp8+W8gDyLBcGcY5m3ugEvKy/ncElxO4d0NtQ==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.cryptography.internal/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.cryptography.internal.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"sha512": "rCQddWkUxGmObeftM0YVyFOPcXkXDEWKGCc4F1viRLEL4ojIbdKwbOYBSf5hfWDR+NO0aGq8r3a8COvNYN/bZA==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.cryptography.keyderivation/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.cryptography.keyderivation.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"sha512": "mtomuG24wGpvdblVQUj/JHIZ1i8oNhRNHr0V0re8fTkv15hz+AQLdtwbdd6FdINNeXiKi3kGmzZ7PE1KOyzoSg==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.identity.entityframeworkcore/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.xml", |
|||
"microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.identity.entityframeworkcore.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"sha512": "9W+IfmAzMrp2ZpKZLhgTlWljSBM9Erldis1us61DAGi+L7Q6vilTbe1G2zDxtYO8F2H0I0Qnupdx5Cp4s2xoZw==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"buildTransitive/net6.0/Microsoft.EntityFrameworkCore.props", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.xml", |
|||
"microsoft.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"sha512": "Pfu3Zjj5+d2Gt27oE9dpGiF/VobBB+s5ogrfI9sBsXQE1SG49RqVz5+IyeNnzhyejFrPIQsPDRMchhcojy4Hbw==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.xml", |
|||
"microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.abstractions.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"sha512": "Qkd2H+jLe37o5ku+LjT6qf7kAHY75Yfn2bBDQgqr13DTOLYpEy1Mt93KPFjaZvIu/srEcbfGGMRL7urKm5zN8Q==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.analyzers/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"analyzers/dotnet/cs/Microsoft.EntityFrameworkCore.Analyzers.dll", |
|||
"lib/netstandard2.0/_._", |
|||
"microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.analyzers.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"sha512": "eQiYygtR2xZ0Uy7KtiFRHpoEx/U8xNwbNRgu1pEJgSxbJLtg6tDL1y2YcIbSuIRSNEljXIIHq/apEhGm1QL70g==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.relational/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.xml", |
|||
"microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.relational.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"sha512": "IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.caching.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Caching.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Caching.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.caching.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"sha512": "xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.caching.memory/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Caching.Memory.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Caching.Memory.targets", |
|||
"lib/net462/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net462/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"microsoft.extensions.caching.memory.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.caching.memory.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"sha512": "f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.configuration.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Configuration.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Configuration.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.configuration.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/8.0.0": { |
|||
"sha512": "V8S3bsm50ig6JSyrbcJJ8bW2b9QLGouz+G1miK3UTaOWmMtFwNNNzUf4AleyDWUmTrWMLNnFSLEQtxmxgNQnNQ==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.dependencyinjection/8.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"PACKAGE.md", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.DependencyInjection.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.targets", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.xml", |
|||
"microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512", |
|||
"microsoft.extensions.dependencyinjection.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": { |
|||
"sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"PACKAGE.md", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", |
|||
"microsoft.extensions.dependencyinjection.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"sha512": "cq11jroq2szFcXLJ0IW5BlI7oqq3ZGCu1mXCnpJ8VIvhvpIzf30AOoWR/w3YRVdAgkYzxbUQpKGZd+oxAKQhLA==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.identity.core/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/net462/Microsoft.Extensions.Identity.Core.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Core.xml", |
|||
"microsoft.extensions.identity.core.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.identity.core.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"sha512": "feaaluQbzJAMMluwSc7Rebm7IEVAD8/5GWt0dMYLE0tcc6gAsHYjBIBrPzmTstORd7k405Qo18FPF/jTfRsM0A==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.identity.stores/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/net462/Microsoft.Extensions.Identity.Stores.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Stores.xml", |
|||
"microsoft.extensions.identity.stores.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.identity.stores.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"sha512": "Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.logging/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Logging.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.targets", |
|||
"lib/net462/Microsoft.Extensions.Logging.dll", |
|||
"lib/net462/Microsoft.Extensions.Logging.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Logging.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Logging.xml", |
|||
"microsoft.extensions.logging.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.logging.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"sha512": "kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.logging.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.logging.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"sha512": "lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.options/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Options.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Options.targets", |
|||
"lib/net462/Microsoft.Extensions.Options.dll", |
|||
"lib/net462/Microsoft.Extensions.Options.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Options.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Options.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Options.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Options.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Options.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Options.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Options.xml", |
|||
"microsoft.extensions.options.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.options.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"sha512": "um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.primitives/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Primitives.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Primitives.targets", |
|||
"lib/net462/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net462/Microsoft.Extensions.Primitives.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Primitives.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Primitives.xml", |
|||
"microsoft.extensions.primitives.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.primitives.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"type": "project", |
|||
"path": "../CellularManagement.Domain/CellularManagement.Domain.csproj", |
|||
"msbuildProject": "../CellularManagement.Domain/CellularManagement.Domain.csproj" |
|||
} |
|||
}, |
|||
"projectFileDependencyGroups": { |
|||
"net8.0": [ |
|||
"CellularManagement.Domain >= 1.0.0", |
|||
"Microsoft.Extensions.DependencyInjection >= 8.0.0" |
|||
] |
|||
}, |
|||
"packageFolders": { |
|||
"C:\\Users\\changeself\\.nuget\\packages\\": {}, |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} |
|||
}, |
|||
"project": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"projectName": "CellularManagement.Application", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
{ |
|||
"version": 2, |
|||
"dgSpecHash": "bWHiEzexJX4=", |
|||
"success": true, |
|||
"projectFilePath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"expectedPackageFiles": [ |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.cryptography.internal\\7.0.0\\microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.cryptography.keyderivation\\7.0.0\\microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.identity.entityframeworkcore\\7.0.0\\microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore\\7.0.0\\microsoft.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\7.0.0\\microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\7.0.0\\microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\7.0.0\\microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\7.0.0\\microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.caching.memory\\7.0.0\\microsoft.extensions.caching.memory.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\7.0.0\\microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\8.0.0\\microsoft.extensions.dependencyinjection.8.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\8.0.0\\microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.identity.core\\7.0.0\\microsoft.extensions.identity.core.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.identity.stores\\7.0.0\\microsoft.extensions.identity.stores.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.logging\\7.0.0\\microsoft.extensions.logging.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\7.0.0\\microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.options\\7.0.0\\microsoft.extensions.options.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.primitives\\7.0.0\\microsoft.extensions.primitives.7.0.0.nupkg.sha512" |
|||
], |
|||
"logs": [] |
|||
} |
@ -0,0 +1,52 @@ |
|||
using System; |
|||
|
|||
namespace CellularManagement.Domain.Abstractions; |
|||
|
|||
/// <summary>
|
|||
/// 可审计实体基类
|
|||
/// 提供审计字段的通用实现
|
|||
/// </summary>
|
|||
public abstract class AuditableEntity : Entity |
|||
{ |
|||
/// <summary>
|
|||
/// 创建时间
|
|||
/// </summary>
|
|||
public DateTime CreatedAt { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// 更新时间
|
|||
/// </summary>
|
|||
public DateTime UpdatedAt { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// 创建人
|
|||
/// </summary>
|
|||
public string? CreatedBy { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// 更新人
|
|||
/// </summary>
|
|||
public string? UpdatedBy { get; protected set; } |
|||
|
|||
/// <summary>
|
|||
/// 设置创建信息
|
|||
/// </summary>
|
|||
/// <param name="userId">创建人ID</param>
|
|||
public void SetCreated(string userId) |
|||
{ |
|||
CreatedAt = DateTime.UtcNow; |
|||
UpdatedAt = CreatedAt; |
|||
CreatedBy = userId; |
|||
UpdatedBy = userId; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 设置更新信息
|
|||
/// </summary>
|
|||
/// <param name="userId">更新人ID</param>
|
|||
public void SetUpdated(string userId) |
|||
{ |
|||
UpdatedAt = DateTime.UtcNow; |
|||
UpdatedBy = userId; |
|||
} |
|||
} |
@ -0,0 +1,51 @@ |
|||
namespace CellularManagement.Domain.Abstractions; |
|||
|
|||
public abstract class Entity |
|||
{ |
|||
public string Id { get; protected set; } |
|||
|
|||
protected Entity() |
|||
{ |
|||
Id = Guid.NewGuid().ToString(); |
|||
} |
|||
|
|||
protected Entity(string id) |
|||
{ |
|||
Id = id; |
|||
} |
|||
|
|||
public override bool Equals(object? obj) |
|||
{ |
|||
if (obj is not Entity other) |
|||
return false; |
|||
|
|||
if (ReferenceEquals(this, other)) |
|||
return true; |
|||
|
|||
if (GetType() != other.GetType()) |
|||
return false; |
|||
|
|||
return Id == other.Id; |
|||
} |
|||
|
|||
public static bool operator ==(Entity? a, Entity? b) |
|||
{ |
|||
if (a is null && b is null) |
|||
return true; |
|||
|
|||
if (a is null || b is null) |
|||
return false; |
|||
|
|||
return a.Equals(b); |
|||
} |
|||
|
|||
public static bool operator !=(Entity? a, Entity? b) |
|||
{ |
|||
return !(a == b); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
return Id.GetHashCode(); |
|||
} |
|||
} |
@ -0,0 +1,14 @@ |
|||
namespace CellularManagement.Domain.Abstractions; |
|||
|
|||
/// <summary>
|
|||
/// 软删除接口
|
|||
/// 用于标记支持软删除的实体
|
|||
/// </summary>
|
|||
public interface ISoftDelete |
|||
{ |
|||
/// <summary>
|
|||
/// 是否已删除
|
|||
/// true 表示已删除,false 表示未删除
|
|||
/// </summary>
|
|||
bool IsDeleted { get; set; } |
|||
} |
@ -0,0 +1,16 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" /> |
|||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,19 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
|
|||
namespace CellularManagement.Domain; |
|||
|
|||
/// <summary>
|
|||
/// 领域层依赖注入扩展
|
|||
/// </summary>
|
|||
public static class DependencyInjection |
|||
{ |
|||
/// <summary>
|
|||
/// 添加领域层服务
|
|||
/// </summary>
|
|||
/// <param name="services">服务集合</param>
|
|||
/// <returns>服务集合</returns>
|
|||
public static IServiceCollection AddDomainServices(this IServiceCollection services) |
|||
{ |
|||
return services; |
|||
} |
|||
} |
@ -0,0 +1,42 @@ |
|||
using Microsoft.AspNetCore.Identity; |
|||
|
|||
namespace CellularManagement.Domain.Entities; |
|||
|
|||
/// <summary>
|
|||
/// 应用程序角色
|
|||
/// 继承自 IdentityRole 以支持身份认证
|
|||
/// </summary>
|
|||
public sealed class AppRole : IdentityRole |
|||
{ |
|||
/// <summary>
|
|||
/// 初始化角色
|
|||
/// 使用 GUID 作为 ID
|
|||
/// </summary>
|
|||
public AppRole() |
|||
{ |
|||
Id = Guid.NewGuid().ToString(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 使用指定的 ID 初始化角色
|
|||
/// </summary>
|
|||
/// <param name="id">角色 ID</param>
|
|||
public AppRole(string id) : base(id) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 使用指定的名称初始化角色
|
|||
/// </summary>
|
|||
/// <param name="roleName">角色名称</param>
|
|||
public AppRole(string roleName, string id) : base(roleName) |
|||
{ |
|||
Id = id; |
|||
} |
|||
|
|||
// Identity 导航属性
|
|||
/// <summary>
|
|||
/// 角色声明集合
|
|||
/// </summary>
|
|||
public ICollection<IdentityRoleClaim<string>> RoleClaims { get; set; } = new List<IdentityRoleClaim<string>>(); |
|||
} |
@ -0,0 +1,20 @@ |
|||
using Microsoft.AspNetCore.Identity; |
|||
|
|||
namespace CellularManagement.Domain.Entities; |
|||
|
|||
/// <summary>
|
|||
/// 应用程序用户
|
|||
/// 继承自 IdentityUser 以支持身份认证
|
|||
/// 提供用户管理、认证和授权的基础功能
|
|||
/// </summary>
|
|||
public sealed class AppUser : IdentityUser |
|||
{ |
|||
/// <summary>
|
|||
/// 初始化用户
|
|||
/// 使用 GUID 作为 ID
|
|||
/// </summary>
|
|||
public AppUser() |
|||
{ |
|||
Id = Guid.NewGuid().ToString(); |
|||
} |
|||
} |
@ -0,0 +1,110 @@ |
|||
using System.Linq.Expressions; |
|||
|
|||
namespace CellularManagement.Domain.Repositories; |
|||
|
|||
/// <summary>
|
|||
/// 命令仓储接口
|
|||
/// 用于处理数据的写入操作(CUD:Create、Update、Delete)
|
|||
/// 遵循 CQRS 模式中的命令部分
|
|||
/// </summary>
|
|||
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
|
|||
/// <remarks>
|
|||
/// 设计说明:
|
|||
/// 1. 接口分离了同步和异步操作
|
|||
/// 2. 只有真正需要等待数据库操作的方法才使用异步
|
|||
/// 3. 更新和删除操作使用同步方法,因为它们只是标记实体状态
|
|||
/// 4. 添加和查询操作使用异步方法,因为它们需要等待数据库操作
|
|||
/// </remarks>
|
|||
public interface ICommandRepository<T> where T : class |
|||
{ |
|||
/// <summary>
|
|||
/// 添加单个实体到数据库
|
|||
/// </summary>
|
|||
/// <param name="entity">要添加的实体</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>添加后的实体</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的插入操作完成
|
|||
/// 实体添加后,其ID和其他数据库生成的字段会被填充
|
|||
/// </remarks>
|
|||
Task<T> AddAsync(T entity, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 批量添加多个实体到数据库
|
|||
/// </summary>
|
|||
/// <param name="entities">要添加的实体集合</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>添加后的实体集合</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的批量插入操作完成
|
|||
/// 批量添加比逐个添加更高效,特别是在大量数据时
|
|||
/// </remarks>
|
|||
Task<IEnumerable<T>> AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 更新单个实体的状态
|
|||
/// </summary>
|
|||
/// <param name="entity">要更新的实体</param>
|
|||
/// <remarks>
|
|||
/// 这是一个同步操作,因为它只是标记实体的状态为已修改
|
|||
/// 实际的数据库更新操作由 UnitOfWork 在事务提交时执行
|
|||
/// </remarks>
|
|||
void Update(T entity); |
|||
|
|||
/// <summary>
|
|||
/// 批量更新多个实体的状态
|
|||
/// </summary>
|
|||
/// <param name="entities">要更新的实体集合</param>
|
|||
/// <remarks>
|
|||
/// 这是一个同步操作,因为它只是标记实体的状态为已修改
|
|||
/// 批量更新比逐个更新更高效,特别是在大量数据时
|
|||
/// </remarks>
|
|||
void UpdateRange(IEnumerable<T> entities); |
|||
|
|||
/// <summary>
|
|||
/// 删除单个实体
|
|||
/// </summary>
|
|||
/// <param name="entity">要删除的实体</param>
|
|||
/// <remarks>
|
|||
/// 这是一个同步操作,因为它只是标记实体的状态为已删除
|
|||
/// 实际的数据库删除操作由 UnitOfWork 在事务提交时执行
|
|||
/// 如果实体实现了 ISoftDelete 接口,将执行软删除
|
|||
/// </remarks>
|
|||
void Delete(T entity); |
|||
|
|||
/// <summary>
|
|||
/// 批量删除多个实体
|
|||
/// </summary>
|
|||
/// <param name="entities">要删除的实体集合</param>
|
|||
/// <remarks>
|
|||
/// 这是一个同步操作,因为它只是标记实体的状态为已删除
|
|||
/// 批量删除比逐个删除更高效,特别是在大量数据时
|
|||
/// </remarks>
|
|||
void DeleteRange(IEnumerable<T> entities); |
|||
|
|||
/// <summary>
|
|||
/// 根据ID删除实体
|
|||
/// </summary>
|
|||
/// <param name="id">要删除的实体的ID</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>是否成功找到并删除实体</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要先查询数据库找到实体
|
|||
/// 如果实体不存在,返回 false
|
|||
/// 如果实体存在,将其标记为已删除
|
|||
/// </remarks>
|
|||
Task<bool> DeleteByIdAsync(string id, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 根据条件删除实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">删除条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>删除的实体数量</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要先查询数据库找到符合条件的实体
|
|||
/// 使用 LINQ 表达式树构建查询条件
|
|||
/// 返回实际删除的实体数量
|
|||
/// </remarks>
|
|||
Task<int> DeleteWhereAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default); |
|||
} |
@ -0,0 +1,124 @@ |
|||
using System.Linq.Expressions; |
|||
|
|||
namespace CellularManagement.Domain.Repositories; |
|||
|
|||
/// <summary>
|
|||
/// 查询仓储接口
|
|||
/// 用于处理数据的读取操作(R:Read)
|
|||
/// 遵循 CQRS 模式中的查询部分
|
|||
/// </summary>
|
|||
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
|
|||
/// <remarks>
|
|||
/// 设计说明:
|
|||
/// 1. 所有方法都是异步的,因为查询操作需要等待数据库响应
|
|||
/// 2. 支持分页查询,提高大数据量查询的性能
|
|||
/// 3. 支持条件查询,使用 LINQ 表达式树构建查询条件
|
|||
/// 4. 支持排序和包含导航属性
|
|||
/// </remarks>
|
|||
public interface IQueryRepository<T> where T : class |
|||
{ |
|||
/// <summary>
|
|||
/// 根据ID查询单个实体
|
|||
/// </summary>
|
|||
/// <param name="id">要查询的实体ID</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>查询到的实体,如果不存在则返回 null</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 使用主键进行查询,性能最优
|
|||
/// </remarks>
|
|||
Task<T?> GetByIdAsync(string id, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 查询所有实体
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>所有实体的集合</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 注意:对于大数据量的表,建议使用分页查询
|
|||
/// </remarks>
|
|||
Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 根据条件查询实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>符合条件的实体集合</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 使用 LINQ 表达式树构建查询条件
|
|||
/// 条件查询会被转换为 SQL 语句在数据库端执行
|
|||
/// </remarks>
|
|||
Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 分页查询实体
|
|||
/// </summary>
|
|||
/// <param name="pageNumber">页码,从1开始</param>
|
|||
/// <param name="pageSize">每页记录数</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 分页查询可以有效减少数据传输量,提高性能
|
|||
/// 建议在查询大数据量时使用
|
|||
/// </remarks>
|
|||
Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync(int pageNumber, int pageSize, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 根据条件分页查询实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="pageNumber">页码,从1开始</param>
|
|||
/// <param name="pageSize">每页记录数</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 结合条件查询和分页查询,适用于大数据量的条件筛选
|
|||
/// </remarks>
|
|||
Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync( |
|||
Expression<Func<T, bool>> predicate, |
|||
int pageNumber, |
|||
int pageSize, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 查询单个实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>查询到的实体,如果不存在则返回 null</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 如果查询结果包含多个实体,将返回第一个
|
|||
/// 建议在确定只会返回一个结果时使用
|
|||
/// </remarks>
|
|||
Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 查询实体是否存在
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>是否存在符合条件的实体</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 使用 EXISTS 语句在数据库端执行,性能优于获取完整实体
|
|||
/// </remarks>
|
|||
Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 统计符合条件的实体数量
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌,用于取消异步操作</param>
|
|||
/// <returns>符合条件的实体数量</returns>
|
|||
/// <remarks>
|
|||
/// 这是一个异步操作,因为需要等待数据库的查询操作完成
|
|||
/// 使用 COUNT 语句在数据库端执行,性能优于获取完整实体
|
|||
/// </remarks>
|
|||
Task<int> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default); |
|||
} |
@ -0,0 +1,62 @@ |
|||
using System.Data; |
|||
using Microsoft.EntityFrameworkCore.Storage; |
|||
|
|||
namespace CellularManagement.Domain.Repositories; |
|||
|
|||
/// <summary>
|
|||
/// 工作单元接口
|
|||
/// 用于管理数据库事务和持久化操作
|
|||
/// </summary>
|
|||
public interface IUnitOfWork : IDisposable |
|||
{ |
|||
/// <summary>
|
|||
/// 保存所有更改到数据库
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>受影响的行数</returns>
|
|||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 开始一个新的事务
|
|||
/// </summary>
|
|||
/// <param name="isolationLevel">事务隔离级别,默认为 ReadCommitted</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>数据库事务对象</returns>
|
|||
Task<IDbContextTransaction> BeginTransactionAsync( |
|||
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 获取当前活动的事务
|
|||
/// </summary>
|
|||
IDbContextTransaction? CurrentTransaction { get; } |
|||
|
|||
/// <summary>
|
|||
/// 检查是否存在活动的事务
|
|||
/// </summary>
|
|||
bool HasActiveTransaction { get; } |
|||
|
|||
/// <summary>
|
|||
/// 提交指定的事务
|
|||
/// </summary>
|
|||
/// <param name="transaction">要提交的事务</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
Task CommitTransactionAsync(IDbContextTransaction transaction, CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 回滚当前活动的事务
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
Task RollbackTransactionAsync(CancellationToken cancellationToken = default); |
|||
|
|||
/// <summary>
|
|||
/// 在事务中执行指定的操作
|
|||
/// </summary>
|
|||
/// <param name="action">要执行的操作</param>
|
|||
/// <param name="isolationLevel">事务隔离级别,默认为 ReadCommitted</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
Task ExecuteTransactionAsync( |
|||
Func<Task> action, |
|||
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, |
|||
CancellationToken cancellationToken = default); |
|||
} |
@ -0,0 +1,345 @@ |
|||
{ |
|||
"runtimeTarget": { |
|||
"name": ".NETCoreApp,Version=v8.0", |
|||
"signature": "" |
|||
}, |
|||
"compilationOptions": {}, |
|||
"targets": { |
|||
".NETCoreApp,Version=v8.0": { |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"CellularManagement.Domain.dll": {} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Relational": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Stores": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Abstractions": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore.Analyzers": "7.0.0", |
|||
"Microsoft.Extensions.Caching.Memory": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": {}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51807" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Core": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51819" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"assemblyVersion": "7.0.0.0", |
|||
"fileVersion": "7.0.22.51805" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"libraries": { |
|||
"CellularManagement.Domain/1.0.0": { |
|||
"type": "project", |
|||
"serviceable": false, |
|||
"sha512": "" |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-hFF+HOqtiNrGtO5ZxLVAFo1ksDLQWf8IHEmGRmcF9azlUWvDLZp8+W8gDyLBcGcY5m3ugEvKy/ncElxO4d0NtQ==", |
|||
"path": "microsoft.aspnetcore.cryptography.internal/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-rCQddWkUxGmObeftM0YVyFOPcXkXDEWKGCc4F1viRLEL4ojIbdKwbOYBSf5hfWDR+NO0aGq8r3a8COvNYN/bZA==", |
|||
"path": "microsoft.aspnetcore.cryptography.keyderivation/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-mtomuG24wGpvdblVQUj/JHIZ1i8oNhRNHr0V0re8fTkv15hz+AQLdtwbdd6FdINNeXiKi3kGmzZ7PE1KOyzoSg==", |
|||
"path": "microsoft.aspnetcore.identity.entityframeworkcore/7.0.0", |
|||
"hashPath": "microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-9W+IfmAzMrp2ZpKZLhgTlWljSBM9Erldis1us61DAGi+L7Q6vilTbe1G2zDxtYO8F2H0I0Qnupdx5Cp4s2xoZw==", |
|||
"path": "microsoft.entityframeworkcore/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Pfu3Zjj5+d2Gt27oE9dpGiF/VobBB+s5ogrfI9sBsXQE1SG49RqVz5+IyeNnzhyejFrPIQsPDRMchhcojy4Hbw==", |
|||
"path": "microsoft.entityframeworkcore.abstractions/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Qkd2H+jLe37o5ku+LjT6qf7kAHY75Yfn2bBDQgqr13DTOLYpEy1Mt93KPFjaZvIu/srEcbfGGMRL7urKm5zN8Q==", |
|||
"path": "microsoft.entityframeworkcore.analyzers/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-eQiYygtR2xZ0Uy7KtiFRHpoEx/U8xNwbNRgu1pEJgSxbJLtg6tDL1y2YcIbSuIRSNEljXIIHq/apEhGm1QL70g==", |
|||
"path": "microsoft.entityframeworkcore.relational/7.0.0", |
|||
"hashPath": "microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==", |
|||
"path": "microsoft.extensions.caching.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==", |
|||
"path": "microsoft.extensions.caching.memory/7.0.0", |
|||
"hashPath": "microsoft.extensions.caching.memory.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==", |
|||
"path": "microsoft.extensions.configuration.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==", |
|||
"path": "microsoft.extensions.dependencyinjection/7.0.0", |
|||
"hashPath": "microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==", |
|||
"path": "microsoft.extensions.dependencyinjection.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-cq11jroq2szFcXLJ0IW5BlI7oqq3ZGCu1mXCnpJ8VIvhvpIzf30AOoWR/w3YRVdAgkYzxbUQpKGZd+oxAKQhLA==", |
|||
"path": "microsoft.extensions.identity.core/7.0.0", |
|||
"hashPath": "microsoft.extensions.identity.core.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-feaaluQbzJAMMluwSc7Rebm7IEVAD8/5GWt0dMYLE0tcc6gAsHYjBIBrPzmTstORd7k405Qo18FPF/jTfRsM0A==", |
|||
"path": "microsoft.extensions.identity.stores/7.0.0", |
|||
"hashPath": "microsoft.extensions.identity.stores.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", |
|||
"path": "microsoft.extensions.logging/7.0.0", |
|||
"hashPath": "microsoft.extensions.logging.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==", |
|||
"path": "microsoft.extensions.logging.abstractions/7.0.0", |
|||
"hashPath": "microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", |
|||
"path": "microsoft.extensions.options/7.0.0", |
|||
"hashPath": "microsoft.extensions.options.7.0.0.nupkg.sha512" |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"type": "package", |
|||
"serviceable": true, |
|||
"sha512": "sha512-um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==", |
|||
"path": "microsoft.extensions.primitives/7.0.0", |
|||
"hashPath": "microsoft.extensions.primitives.7.0.0.nupkg.sha512" |
|||
} |
|||
} |
|||
} |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,88 @@ |
|||
{ |
|||
"format": 1, |
|||
"restore": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": {} |
|||
}, |
|||
"projects": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"projectName": "CellularManagement.Domain", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": {} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess> |
|||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool> |
|||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile> |
|||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot> |
|||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\changeself\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders> |
|||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle> |
|||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.12.2</NuGetToolVersion> |
|||
</PropertyGroup> |
|||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<SourceRoot Include="C:\Users\changeself\.nuget\packages\" /> |
|||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" /> |
|||
</ItemGroup> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.0\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.0\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" /> |
|||
</ImportGroup> |
|||
</Project> |
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> |
|||
</ImportGroup> |
|||
</Project> |
@ -0,0 +1,4 @@ |
|||
// <autogenerated />
|
|||
using System; |
|||
using System.Reflection; |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] |
@ -0,0 +1,22 @@ |
|||
//------------------------------------------------------------------------------
|
|||
// <auto-generated>
|
|||
// This code was generated by a tool.
|
|||
//
|
|||
// Changes to this file may cause incorrect behavior and will be lost if
|
|||
// the code is regenerated.
|
|||
// </auto-generated>
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
using System; |
|||
using System.Reflection; |
|||
|
|||
[assembly: System.Reflection.AssemblyCompanyAttribute("CellularManagement.Domain")] |
|||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] |
|||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] |
|||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] |
|||
[assembly: System.Reflection.AssemblyProductAttribute("CellularManagement.Domain")] |
|||
[assembly: System.Reflection.AssemblyTitleAttribute("CellularManagement.Domain")] |
|||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] |
|||
|
|||
// 由 MSBuild WriteCodeFragment 类生成。
|
|||
|
@ -0,0 +1 @@ |
|||
12e431942fef011f2b9b1a9adf8ef5e43c8f65aad53fe3677eb3730c08dcdf15 |
@ -0,0 +1,15 @@ |
|||
is_global = true |
|||
build_property.TargetFramework = net8.0 |
|||
build_property.TargetPlatformMinVersion = |
|||
build_property.UsingMicrosoftNETSdkWeb = |
|||
build_property.ProjectTypeGuids = |
|||
build_property.InvariantGlobalization = |
|||
build_property.PlatformNeutralAssembly = |
|||
build_property.EnforceExtendedAnalyzerRules = |
|||
build_property._SupportedPlatformList = Linux,macOS,Windows |
|||
build_property.RootNamespace = CellularManagement.Domain |
|||
build_property.ProjectDir = D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\ |
|||
build_property.EnableComHosting = |
|||
build_property.EnableGeneratedComInterfaceComImportInterop = |
|||
build_property.EffectiveAnalysisLevelStyle = 8.0 |
|||
build_property.EnableCodeStyleSeverity = |
@ -0,0 +1,8 @@ |
|||
// <auto-generated/>
|
|||
global using global::System; |
|||
global using global::System.Collections.Generic; |
|||
global using global::System.IO; |
|||
global using global::System.Linq; |
|||
global using global::System.Net.Http; |
|||
global using global::System.Threading; |
|||
global using global::System.Threading.Tasks; |
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||
a4bcae8e8ce93538b276fc138f03b772b3319b2f2b20111afaa80647e7bee50a |
@ -0,0 +1,12 @@ |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\bin\Debug\net8.0\CellularManagement.Domain.deps.json |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\bin\Debug\net8.0\CellularManagement.Domain.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\bin\Debug\net8.0\CellularManagement.Domain.pdb |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.csproj.AssemblyReference.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.GeneratedMSBuildEditorConfig.editorconfig |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.AssemblyInfoInputs.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.AssemblyInfo.cs |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.csproj.CoreCompileInputs.cache |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\refint\CellularManagement.Domain.dll |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\CellularManagement.Domain.pdb |
|||
D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Domain\obj\Debug\net8.0\ref\CellularManagement.Domain.dll |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,856 @@ |
|||
{ |
|||
"version": 3, |
|||
"targets": { |
|||
"net8.0": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Relational": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Stores": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore.Abstractions": "7.0.0", |
|||
"Microsoft.EntityFrameworkCore.Analyzers": "7.0.0", |
|||
"Microsoft.Extensions.Caching.Memory": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/Microsoft.EntityFrameworkCore.props": {} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/netstandard2.0/_._": {} |
|||
}, |
|||
"runtime": { |
|||
"lib/netstandard2.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.EntityFrameworkCore": "7.0.0", |
|||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Identity.Core": "7.0.0", |
|||
"Microsoft.Extensions.Logging": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll": { |
|||
"related": ".xml" |
|||
} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": "7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Logging.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Options": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"type": "package", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0", |
|||
"Microsoft.Extensions.Primitives": "7.0.0" |
|||
}, |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"type": "package", |
|||
"compile": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"runtime": { |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": { |
|||
"related": ".xml" |
|||
} |
|||
}, |
|||
"build": { |
|||
"buildTransitive/net6.0/_._": {} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"libraries": { |
|||
"Microsoft.AspNetCore.Cryptography.Internal/7.0.0": { |
|||
"sha512": "hFF+HOqtiNrGtO5ZxLVAFo1ksDLQWf8IHEmGRmcF9azlUWvDLZp8+W8gDyLBcGcY5m3ugEvKy/ncElxO4d0NtQ==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.cryptography.internal/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.dll", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.Internal.xml", |
|||
"microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.cryptography.internal.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.AspNetCore.Cryptography.KeyDerivation/7.0.0": { |
|||
"sha512": "rCQddWkUxGmObeftM0YVyFOPcXkXDEWKGCc4F1viRLEL4ojIbdKwbOYBSf5hfWDR+NO0aGq8r3a8COvNYN/bZA==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.cryptography.keyderivation/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/net462/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.dll", |
|||
"lib/netstandard2.0/Microsoft.AspNetCore.Cryptography.KeyDerivation.xml", |
|||
"microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.cryptography.keyderivation.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore/7.0.0": { |
|||
"sha512": "mtomuG24wGpvdblVQUj/JHIZ1i8oNhRNHr0V0re8fTkv15hz+AQLdtwbdd6FdINNeXiKi3kGmzZ7PE1KOyzoSg==", |
|||
"type": "package", |
|||
"path": "microsoft.aspnetcore.identity.entityframeworkcore/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll", |
|||
"lib/net7.0/Microsoft.AspNetCore.Identity.EntityFrameworkCore.xml", |
|||
"microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"microsoft.aspnetcore.identity.entityframeworkcore.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore/7.0.0": { |
|||
"sha512": "9W+IfmAzMrp2ZpKZLhgTlWljSBM9Erldis1us61DAGi+L7Q6vilTbe1G2zDxtYO8F2H0I0Qnupdx5Cp4s2xoZw==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"buildTransitive/net6.0/Microsoft.EntityFrameworkCore.props", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.xml", |
|||
"microsoft.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Abstractions/7.0.0": { |
|||
"sha512": "Pfu3Zjj5+d2Gt27oE9dpGiF/VobBB+s5ogrfI9sBsXQE1SG49RqVz5+IyeNnzhyejFrPIQsPDRMchhcojy4Hbw==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Abstractions.xml", |
|||
"microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.abstractions.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Analyzers/7.0.0": { |
|||
"sha512": "Qkd2H+jLe37o5ku+LjT6qf7kAHY75Yfn2bBDQgqr13DTOLYpEy1Mt93KPFjaZvIu/srEcbfGGMRL7urKm5zN8Q==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.analyzers/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"analyzers/dotnet/cs/Microsoft.EntityFrameworkCore.Analyzers.dll", |
|||
"lib/netstandard2.0/_._", |
|||
"microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.analyzers.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Relational/7.0.0": { |
|||
"sha512": "eQiYygtR2xZ0Uy7KtiFRHpoEx/U8xNwbNRgu1pEJgSxbJLtg6tDL1y2YcIbSuIRSNEljXIIHq/apEhGm1QL70g==", |
|||
"type": "package", |
|||
"path": "microsoft.entityframeworkcore.relational/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.dll", |
|||
"lib/net6.0/Microsoft.EntityFrameworkCore.Relational.xml", |
|||
"microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512", |
|||
"microsoft.entityframeworkcore.relational.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": { |
|||
"sha512": "IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.caching.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Caching.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Caching.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Abstractions.xml", |
|||
"microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.caching.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Caching.Memory/7.0.0": { |
|||
"sha512": "xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.caching.memory/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Caching.Memory.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Caching.Memory.targets", |
|||
"lib/net462/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net462/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Caching.Memory.xml", |
|||
"microsoft.extensions.caching.memory.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.caching.memory.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": { |
|||
"sha512": "f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.configuration.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Configuration.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Configuration.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.xml", |
|||
"microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.configuration.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection/7.0.0": { |
|||
"sha512": "elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.dependencyinjection/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.DependencyInjection.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.targets", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.xml", |
|||
"microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.dependencyinjection.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": { |
|||
"sha512": "h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.dependencyinjection.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml", |
|||
"microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.dependencyinjection.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Identity.Core/7.0.0": { |
|||
"sha512": "cq11jroq2szFcXLJ0IW5BlI7oqq3ZGCu1mXCnpJ8VIvhvpIzf30AOoWR/w3YRVdAgkYzxbUQpKGZd+oxAKQhLA==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.identity.core/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/net462/Microsoft.Extensions.Identity.Core.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Core.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Core.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Core.xml", |
|||
"microsoft.extensions.identity.core.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.identity.core.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Identity.Stores/7.0.0": { |
|||
"sha512": "feaaluQbzJAMMluwSc7Rebm7IEVAD8/5GWt0dMYLE0tcc6gAsHYjBIBrPzmTstORd7k405Qo18FPF/jTfRsM0A==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.identity.stores/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"lib/net462/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/net462/Microsoft.Extensions.Identity.Stores.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Identity.Stores.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Stores.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Identity.Stores.xml", |
|||
"microsoft.extensions.identity.stores.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.identity.stores.nuspec" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Logging/7.0.0": { |
|||
"sha512": "Nw2muoNrOG5U5qa2ZekXwudUn2BJcD41e65zwmDHb1fQegTX66UokLWZkJRpqSSHXDOWZ5V0iqhbxOEky91atA==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.logging/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Logging.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.targets", |
|||
"lib/net462/Microsoft.Extensions.Logging.dll", |
|||
"lib/net462/Microsoft.Extensions.Logging.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Logging.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Logging.xml", |
|||
"microsoft.extensions.logging.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.logging.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Logging.Abstractions/7.0.0": { |
|||
"sha512": "kmn78+LPVMOWeITUjIlfxUPDsI0R6G0RkeAMBmQxAJ7vBJn4q2dTva7pWi65ceN5vPGjJ9q/Uae2WKgvfktJAw==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.logging.abstractions/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll", |
|||
"buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets", |
|||
"lib/net462/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net462/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml", |
|||
"microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.logging.abstractions.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Options/7.0.0": { |
|||
"sha512": "lP1yBnTTU42cKpMozuafbvNtQ7QcBjr/CcK3bYOGEMH55Fjt+iecXjT6chR7vbgCMqy3PG3aNQSZgo/EuY/9qQ==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.options/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Options.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Options.targets", |
|||
"lib/net462/Microsoft.Extensions.Options.dll", |
|||
"lib/net462/Microsoft.Extensions.Options.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Options.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Options.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Options.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Options.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Options.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Options.xml", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Options.dll", |
|||
"lib/netstandard2.1/Microsoft.Extensions.Options.xml", |
|||
"microsoft.extensions.options.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.options.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
}, |
|||
"Microsoft.Extensions.Primitives/7.0.0": { |
|||
"sha512": "um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==", |
|||
"type": "package", |
|||
"path": "microsoft.extensions.primitives/7.0.0", |
|||
"files": [ |
|||
".nupkg.metadata", |
|||
".signature.p7s", |
|||
"Icon.png", |
|||
"LICENSE.TXT", |
|||
"THIRD-PARTY-NOTICES.TXT", |
|||
"buildTransitive/net461/Microsoft.Extensions.Primitives.targets", |
|||
"buildTransitive/net462/_._", |
|||
"buildTransitive/net6.0/_._", |
|||
"buildTransitive/netcoreapp2.0/Microsoft.Extensions.Primitives.targets", |
|||
"lib/net462/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net462/Microsoft.Extensions.Primitives.xml", |
|||
"lib/net6.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net6.0/Microsoft.Extensions.Primitives.xml", |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/net7.0/Microsoft.Extensions.Primitives.xml", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Primitives.dll", |
|||
"lib/netstandard2.0/Microsoft.Extensions.Primitives.xml", |
|||
"microsoft.extensions.primitives.7.0.0.nupkg.sha512", |
|||
"microsoft.extensions.primitives.nuspec", |
|||
"useSharedDesignerContext.txt" |
|||
] |
|||
} |
|||
}, |
|||
"projectFileDependencyGroups": { |
|||
"net8.0": [ |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore >= 7.0.0", |
|||
"Microsoft.EntityFrameworkCore >= 7.0.0", |
|||
"Microsoft.Extensions.DependencyInjection >= 7.0.0" |
|||
] |
|||
}, |
|||
"packageFolders": { |
|||
"C:\\Users\\changeself\\.nuget\\packages\\": {}, |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages": {} |
|||
}, |
|||
"project": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"projectName": "CellularManagement.Domain", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": {} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
{ |
|||
"version": 2, |
|||
"dgSpecHash": "M9DaSeXNF/Y=", |
|||
"success": true, |
|||
"projectFilePath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"expectedPackageFiles": [ |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.cryptography.internal\\7.0.0\\microsoft.aspnetcore.cryptography.internal.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.cryptography.keyderivation\\7.0.0\\microsoft.aspnetcore.cryptography.keyderivation.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.aspnetcore.identity.entityframeworkcore\\7.0.0\\microsoft.aspnetcore.identity.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore\\7.0.0\\microsoft.entityframeworkcore.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\7.0.0\\microsoft.entityframeworkcore.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\7.0.0\\microsoft.entityframeworkcore.analyzers.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\7.0.0\\microsoft.entityframeworkcore.relational.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\7.0.0\\microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.caching.memory\\7.0.0\\microsoft.extensions.caching.memory.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\7.0.0\\microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\7.0.0\\microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\7.0.0\\microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.identity.core\\7.0.0\\microsoft.extensions.identity.core.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.identity.stores\\7.0.0\\microsoft.extensions.identity.stores.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.logging\\7.0.0\\microsoft.extensions.logging.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\7.0.0\\microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.options\\7.0.0\\microsoft.extensions.options.7.0.0.nupkg.sha512", |
|||
"C:\\Users\\changeself\\.nuget\\packages\\microsoft.extensions.primitives\\7.0.0\\microsoft.extensions.primitives.7.0.0.nupkg.sha512" |
|||
], |
|||
"logs": [] |
|||
} |
@ -0,0 +1,13 @@ |
|||
{ |
|||
"version": 1, |
|||
"isRoot": true, |
|||
"tools": { |
|||
"dotnet-ef": { |
|||
"version": "8.0.0", |
|||
"commands": [ |
|||
"dotnet-ef" |
|||
], |
|||
"rollForward": false |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<Nullable>enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\CellularManagement.Domain\CellularManagement.Domain.csproj" /> |
|||
<ProjectReference Include="..\CellularManagement.Application\CellularManagement.Application.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0"> |
|||
<PrivateAssets>all</PrivateAssets> |
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
|||
</PackageReference> |
|||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> |
|||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" /> |
|||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" /> |
|||
<PackageReference Include="Scrutor" Version="4.2.2" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,54 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
using CellularManagement.Domain.Entities; |
|||
|
|||
namespace CellularManagement.Infrastructure.Configurations; |
|||
|
|||
/// <summary>
|
|||
/// AppRole 实体配置类
|
|||
/// </summary>
|
|||
public sealed class AppRoleConfiguration : IEntityTypeConfiguration<AppRole> |
|||
{ |
|||
/// <summary>
|
|||
/// 配置 AppRole 实体
|
|||
/// </summary>
|
|||
/// <param name="builder">实体类型构建器</param>
|
|||
public void Configure(EntityTypeBuilder<AppRole> builder) |
|||
{ |
|||
// 配置表名
|
|||
builder.ToTable("Roles", t => t.HasComment("角色表")); |
|||
|
|||
// 配置索引
|
|||
builder.HasIndex(r => r.Name) |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Roles_Name"); |
|||
|
|||
builder.HasIndex(r => r.NormalizedName) |
|||
.IsUnique() |
|||
.HasDatabaseName("RoleNameIndex"); |
|||
|
|||
// 配置属性
|
|||
builder.Property(r => r.Id) |
|||
.HasComment("角色ID,主键"); |
|||
|
|||
builder.Property(r => r.Name) |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasComment("角色名称"); |
|||
|
|||
builder.Property(r => r.NormalizedName) |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasComment("标准化角色名称(大写)"); |
|||
|
|||
builder.Property(r => r.ConcurrencyStamp) |
|||
.IsConcurrencyToken() |
|||
.HasComment("并发控制戳"); |
|||
|
|||
// 配置关系
|
|||
builder.HasMany(r => r.RoleClaims) |
|||
.WithOne() |
|||
.HasForeignKey(rc => rc.RoleId) |
|||
.IsRequired(); |
|||
} |
|||
} |
@ -0,0 +1,83 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
using CellularManagement.Domain.Entities; |
|||
|
|||
namespace CellularManagement.Infrastructure.Configurations; |
|||
|
|||
/// <summary>
|
|||
/// AppUser 实体配置类
|
|||
/// 用于配置用户实体在数据库中的映射关系
|
|||
/// </summary>
|
|||
public sealed class AppUserConfiguration : IEntityTypeConfiguration<AppUser> |
|||
{ |
|||
/// <summary>
|
|||
/// 配置 AppUser 实体
|
|||
/// </summary>
|
|||
/// <param name="builder">实体类型构建器</param>
|
|||
public void Configure(EntityTypeBuilder<AppUser> builder) |
|||
{ |
|||
// 配置表名
|
|||
builder.ToTable("Users", t => t.HasComment("用户表")); |
|||
|
|||
// 配置索引
|
|||
builder.HasIndex(u => u.UserName).IsUnique().HasDatabaseName("IX_Users_UserName"); |
|||
builder.HasIndex(u => u.Email).IsUnique().HasDatabaseName("IX_Users_Email"); |
|||
builder.HasIndex(u => u.PhoneNumber).IsUnique().HasDatabaseName("IX_Users_PhoneNumber"); |
|||
builder.HasIndex(u => u.NormalizedEmail).HasDatabaseName("EmailIndex"); |
|||
builder.HasIndex(u => u.NormalizedUserName).IsUnique().HasDatabaseName("UserNameIndex"); |
|||
|
|||
// 配置属性
|
|||
builder.Property(u => u.Id) |
|||
.HasComment("用户ID,主键"); |
|||
|
|||
builder.Property(u => u.UserName) |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasComment("用户名"); |
|||
|
|||
builder.Property(u => u.NormalizedUserName) |
|||
.HasMaxLength(256) |
|||
.HasComment("标准化用户名(大写)"); |
|||
|
|||
builder.Property(u => u.Email) |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasComment("电子邮箱"); |
|||
|
|||
builder.Property(u => u.NormalizedEmail) |
|||
.HasMaxLength(256) |
|||
.HasComment("标准化电子邮箱(大写)"); |
|||
|
|||
builder.Property(u => u.EmailConfirmed) |
|||
.HasComment("邮箱是否已验证"); |
|||
|
|||
builder.Property(u => u.PasswordHash) |
|||
.HasComment("密码哈希值"); |
|||
|
|||
builder.Property(u => u.SecurityStamp) |
|||
.HasComment("安全戳,用于并发控制"); |
|||
|
|||
builder.Property(u => u.ConcurrencyStamp) |
|||
.IsConcurrencyToken() |
|||
.HasComment("并发控制戳"); |
|||
|
|||
builder.Property(u => u.PhoneNumber) |
|||
.IsRequired() |
|||
.HasComment("电话号码"); |
|||
|
|||
builder.Property(u => u.PhoneNumberConfirmed) |
|||
.HasComment("电话号码是否已验证"); |
|||
|
|||
builder.Property(u => u.TwoFactorEnabled) |
|||
.HasComment("是否启用双因素认证"); |
|||
|
|||
builder.Property(u => u.LockoutEnd) |
|||
.HasComment("账户锁定结束时间"); |
|||
|
|||
builder.Property(u => u.LockoutEnabled) |
|||
.HasComment("是否启用账户锁定"); |
|||
|
|||
builder.Property(u => u.AccessFailedCount) |
|||
.HasComment("登录失败次数"); |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
|||
using CellularManagement.Domain.Abstractions; |
|||
|
|||
namespace CellularManagement.Infrastructure.Configurations; |
|||
|
|||
/// <summary>
|
|||
/// 基础实体配置类
|
|||
/// 包含审计字段的通用配置,为所有可审计实体提供统一的数据库映射配置
|
|||
/// </summary>
|
|||
/// <typeparam name="TEntity">实体类型,必须继承自 AuditableEntity</typeparam>
|
|||
public abstract class BaseEntityConfiguration<TEntity> : IEntityTypeConfiguration<TEntity> |
|||
where TEntity : AuditableEntity |
|||
{ |
|||
/// <summary>
|
|||
/// 配置基础实体
|
|||
/// 设置实体的主键和审计字段的数据库映射
|
|||
/// </summary>
|
|||
/// <param name="builder">实体类型构建器,用于配置实体的数据库映射</param>
|
|||
public virtual void Configure(EntityTypeBuilder<TEntity> builder) |
|||
{ |
|||
// 配置主键
|
|||
// 使用 Id 作为实体的主键
|
|||
builder.HasKey(e => e.Id); |
|||
|
|||
// 配置审计字段
|
|||
// 创建时间:必填字段,记录实体的创建时间
|
|||
builder.Property(e => e.CreatedAt) |
|||
.IsRequired(); |
|||
|
|||
// 更新时间:必填字段,记录实体的最后更新时间
|
|||
builder.Property(e => e.UpdatedAt) |
|||
.IsRequired(); |
|||
|
|||
// 创建人:可选字段,最大长度256,记录创建实体的用户ID
|
|||
builder.Property(e => e.CreatedBy) |
|||
.HasMaxLength(256); |
|||
|
|||
// 更新人:可选字段,最大长度256,记录最后更新实体的用户ID
|
|||
builder.Property(e => e.UpdatedBy) |
|||
.HasMaxLength(256); |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using CellularManagement.Domain.Entities; |
|||
|
|||
namespace CellularManagement.Infrastructure.Context; |
|||
|
|||
/// <summary>
|
|||
/// 应用程序数据库上下文
|
|||
/// 继承自 IdentityDbContext 以支持身份认证
|
|||
/// </summary>
|
|||
public class AppDbContext : IdentityDbContext<AppUser, AppRole, string> |
|||
{ |
|||
private readonly ILogger<AppDbContext> _logger; |
|||
|
|||
/// <summary>
|
|||
/// 初始化数据库上下文
|
|||
/// </summary>
|
|||
/// <param name="options">数据库上下文选项</param>
|
|||
/// <param name="logger">日志记录器</param>
|
|||
public AppDbContext(DbContextOptions<AppDbContext> options, ILogger<AppDbContext> logger) |
|||
: base(options) |
|||
{ |
|||
_logger = logger; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 配置实体模型
|
|||
/// </summary>
|
|||
/// <param name="modelBuilder">模型构建器</param>
|
|||
protected override void OnModelCreating(ModelBuilder modelBuilder) |
|||
{ |
|||
base.OnModelCreating(modelBuilder); |
|||
|
|||
// 应用所有的实体配置
|
|||
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly); |
|||
|
|||
// 忽略 Identity 相关的实体
|
|||
modelBuilder.Ignore<IdentityUserLogin<string>>(); |
|||
modelBuilder.Ignore<IdentityRoleClaim<string>>(); |
|||
modelBuilder.Ignore<IdentityUserClaim<string>>(); |
|||
modelBuilder.Ignore<IdentityUserToken<string>>(); |
|||
modelBuilder.Ignore<IdentityUserRole<string>>(); |
|||
} |
|||
} |
@ -0,0 +1,271 @@ |
|||
using System.Data; |
|||
using Microsoft.EntityFrameworkCore.Storage; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using CellularManagement.Domain.Repositories; |
|||
using Microsoft.Extensions.Logging; |
|||
using CellularManagement.Domain.Abstractions; |
|||
|
|||
namespace CellularManagement.Infrastructure.Context; |
|||
|
|||
/// <summary>
|
|||
/// 工作单元实现类
|
|||
/// 负责管理数据库事务和持久化操作
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 使用 Entity Framework Core 的事务管理
|
|||
/// 2. 支持事务的自动提交和回滚
|
|||
/// 3. 实现了审计字段的自动更新
|
|||
/// 4. 支持软删除功能
|
|||
/// 5. 使用日志记录器记录错误信息
|
|||
/// </remarks>
|
|||
public class UnitOfWork : IUnitOfWork |
|||
{ |
|||
/// <summary>
|
|||
/// 数据库上下文
|
|||
/// </summary>
|
|||
private readonly AppDbContext _context; |
|||
|
|||
/// <summary>
|
|||
/// 日志记录器
|
|||
/// </summary>
|
|||
private readonly ILogger<UnitOfWork> _logger; |
|||
|
|||
/// <summary>
|
|||
/// 当前活动的事务
|
|||
/// </summary>
|
|||
private IDbContextTransaction? _currentTransaction; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
/// <param name="context">数据库上下文</param>
|
|||
/// <param name="logger">日志记录器</param>
|
|||
public UnitOfWork(AppDbContext context, ILogger<UnitOfWork> logger) |
|||
{ |
|||
_context = context; |
|||
_logger = logger; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取当前活动的事务
|
|||
/// </summary>
|
|||
public IDbContextTransaction? CurrentTransaction => _currentTransaction; |
|||
|
|||
/// <summary>
|
|||
/// 检查是否存在活动的事务
|
|||
/// </summary>
|
|||
public bool HasActiveTransaction => _currentTransaction != null; |
|||
|
|||
/// <summary>
|
|||
/// 保存所有更改到数据库
|
|||
/// 同时处理审计字段(创建时间、更新时间)和软删除
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>受影响的行数</returns>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 自动更新实体的创建时间和更新时间
|
|||
/// 2. 对于删除操作,如果实体支持软删除,则执行软删除
|
|||
/// 3. 使用 UTC 时间确保时间一致性
|
|||
/// 4. 记录错误日志
|
|||
/// </remarks>
|
|||
public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) |
|||
{ |
|||
try |
|||
{ |
|||
var now = DateTime.UtcNow; |
|||
var entries = _context.ChangeTracker.Entries<AuditableEntity>(); |
|||
|
|||
foreach (var entry in entries) |
|||
{ |
|||
if (entry.Entity == null) continue; |
|||
|
|||
switch (entry.State) |
|||
{ |
|||
case EntityState.Added: |
|||
// 设置创建时间和更新时间
|
|||
if (entry.Property(p => p.CreatedAt).CurrentValue == default) |
|||
entry.Property(p => p.CreatedAt).CurrentValue = now; |
|||
if (entry.Property(p => p.UpdatedAt).CurrentValue == default) |
|||
entry.Property(p => p.UpdatedAt).CurrentValue = now; |
|||
break; |
|||
|
|||
case EntityState.Modified: |
|||
// 更新修改时间
|
|||
entry.Property(p => p.UpdatedAt).CurrentValue = now; |
|||
break; |
|||
|
|||
case EntityState.Deleted: |
|||
// 实现软删除:将删除操作转换为更新操作
|
|||
entry.State = EntityState.Modified; |
|||
entry.Property(p => p.UpdatedAt).CurrentValue = now; |
|||
if (entry.Entity is ISoftDelete softDeleteEntity) |
|||
{ |
|||
softDeleteEntity.IsDeleted = true; |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return await _context.SaveChangesAsync(cancellationToken); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "保存更改时发生错误"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 开始一个新的事务
|
|||
/// </summary>
|
|||
/// <param name="isolationLevel">事务隔离级别,默认为 ReadCommitted</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>数据库事务对象</returns>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 检查是否已存在活动的事务
|
|||
/// 2. 创建新的事务并保存到 _currentTransaction
|
|||
/// 3. 如果创建失败,记录错误日志
|
|||
/// </remarks>
|
|||
public async Task<IDbContextTransaction> BeginTransactionAsync( |
|||
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
if (_currentTransaction != null) |
|||
{ |
|||
throw new InvalidOperationException("已经存在活动的事务"); |
|||
} |
|||
|
|||
try |
|||
{ |
|||
_currentTransaction = await _context.Database.BeginTransactionAsync(isolationLevel, cancellationToken); |
|||
return _currentTransaction; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "开始事务时发生错误"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 提交指定的事务
|
|||
/// </summary>
|
|||
/// <param name="transaction">要提交的事务</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 检查事务是否有效
|
|||
/// 2. 提交事务并释放资源
|
|||
/// 3. 清除当前事务引用
|
|||
/// 4. 如果提交失败,记录错误日志
|
|||
/// </remarks>
|
|||
public async Task CommitTransactionAsync(IDbContextTransaction transaction, CancellationToken cancellationToken = default) |
|||
{ |
|||
if (transaction == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(transaction)); |
|||
} |
|||
|
|||
if (transaction != _currentTransaction) |
|||
{ |
|||
throw new InvalidOperationException("提交的事务与当前活动的事务不匹配"); |
|||
} |
|||
|
|||
try |
|||
{ |
|||
await transaction.CommitAsync(cancellationToken); |
|||
await transaction.DisposeAsync(); |
|||
_currentTransaction = null; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "提交事务时发生错误"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 回滚当前活动的事务
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 检查是否存在活动的事务
|
|||
/// 2. 回滚事务并释放资源
|
|||
/// 3. 清除当前事务引用
|
|||
/// 4. 如果回滚失败,记录错误日志
|
|||
/// </remarks>
|
|||
public async Task RollbackTransactionAsync(CancellationToken cancellationToken = default) |
|||
{ |
|||
if (_currentTransaction == null) |
|||
{ |
|||
throw new InvalidOperationException("没有活动的事务可以回滚"); |
|||
} |
|||
|
|||
try |
|||
{ |
|||
await _currentTransaction.RollbackAsync(cancellationToken); |
|||
await _currentTransaction.DisposeAsync(); |
|||
_currentTransaction = null; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "回滚事务时发生错误"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 在事务中执行指定的操作
|
|||
/// 如果操作成功则提交事务,失败则回滚
|
|||
/// </summary>
|
|||
/// <param name="action">要执行的操作</param>
|
|||
/// <param name="isolationLevel">事务隔离级别,默认为 ReadCommitted</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 开始新的事务
|
|||
/// 2. 执行指定的操作
|
|||
/// 3. 如果操作成功,提交事务
|
|||
/// 4. 如果操作失败,回滚事务
|
|||
/// 5. 确保事务资源被正确释放
|
|||
/// </remarks>
|
|||
public async Task ExecuteTransactionAsync( |
|||
Func<Task> action, |
|||
IsolationLevel isolationLevel = IsolationLevel.ReadCommitted, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
if (action == null) |
|||
{ |
|||
throw new ArgumentNullException(nameof(action)); |
|||
} |
|||
|
|||
var transaction = await BeginTransactionAsync(isolationLevel, cancellationToken); |
|||
try |
|||
{ |
|||
await action(); |
|||
await CommitTransactionAsync(transaction, cancellationToken); |
|||
} |
|||
catch |
|||
{ |
|||
await RollbackTransactionAsync(cancellationToken); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 释放资源
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 释放当前活动的事务
|
|||
/// 2. 确保所有资源都被正确释放
|
|||
/// </remarks>
|
|||
public void Dispose() |
|||
{ |
|||
_currentTransaction?.Dispose(); |
|||
} |
|||
} |
@ -0,0 +1,140 @@ |
|||
using CellularManagement.Infrastructure.Context; |
|||
using CellularManagement.Infrastructure.Options; |
|||
using CellularManagement.Infrastructure.Repositories; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using CellularManagement.Domain.Entities; |
|||
using CellularManagement.Domain.Repositories; |
|||
using CellularManagement.Domain.Abstractions; |
|||
using CellularManagement.Application.Services; |
|||
using CellularManagement.Infrastructure.Services; |
|||
using System.Text; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Scrutor; |
|||
|
|||
namespace CellularManagement.Infrastructure; |
|||
|
|||
/// <summary>
|
|||
/// 依赖注入扩展方法
|
|||
/// </summary>
|
|||
public static class DependencyInjection |
|||
{ |
|||
/// <summary>
|
|||
/// 添加基础设施服务
|
|||
/// </summary>
|
|||
/// <param name="services">服务集合</param>
|
|||
/// <param name="configuration">配置</param>
|
|||
/// <returns>服务集合</returns>
|
|||
public static IServiceCollection AddInfrastructure( |
|||
this IServiceCollection services, |
|||
IConfiguration configuration) |
|||
{ |
|||
ArgumentNullException.ThrowIfNull(services); |
|||
ArgumentNullException.ThrowIfNull(configuration); |
|||
|
|||
var assembly = typeof(DependencyInjection).Assembly; |
|||
var databaseOptions = configuration |
|||
.GetSection(DatabaseOptions.SectionName) |
|||
.Get<DatabaseOptions>(); |
|||
|
|||
if (databaseOptions is null) |
|||
{ |
|||
throw new ArgumentNullException( |
|||
nameof(databaseOptions), |
|||
"Database options not configured"); |
|||
} |
|||
|
|||
// 配置 JWT 选项
|
|||
services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.SectionName)); |
|||
services.ConfigureOptions<JwtBearerOptionsSetup>(); |
|||
|
|||
// 配置数据库选项
|
|||
services.Configure<DatabaseOptions>(configuration.GetSection(DatabaseOptions.SectionName)); |
|||
var databaseOptionsConfig = configuration.GetSection(DatabaseOptions.SectionName).Get<DatabaseOptions>(); |
|||
|
|||
if (databaseOptionsConfig?.DefaultConnection is null) |
|||
{ |
|||
throw new ArgumentNullException( |
|||
nameof(databaseOptionsConfig.DefaultConnection), |
|||
"Database connection string not configured"); |
|||
} |
|||
|
|||
// 注册密钥轮换服务
|
|||
services.AddSingleton<IKeyRotationService, KeyRotationService>(); |
|||
services.AddHostedService<KeyRotationBackgroundService>(); |
|||
|
|||
// 配置数据库上下文
|
|||
services.AddDbContext<AppDbContext>(options => |
|||
{ |
|||
// 使用 PostgreSQL 数据库
|
|||
options.UseNpgsql( |
|||
databaseOptionsConfig.DefaultConnection, |
|||
sqlOptions => |
|||
{ |
|||
// 配置重试策略
|
|||
sqlOptions.EnableRetryOnFailure(3); |
|||
// 配置命令超时时间
|
|||
sqlOptions.CommandTimeout(databaseOptionsConfig.CommandTimeout); |
|||
}); |
|||
|
|||
// 配置详细错误信息
|
|||
if (databaseOptionsConfig.EnableDetailedErrors) |
|||
{ |
|||
options.EnableDetailedErrors(); |
|||
} |
|||
|
|||
// 配置敏感数据日志记录
|
|||
if (databaseOptionsConfig.EnableSensitiveDataLogging) |
|||
{ |
|||
options.EnableSensitiveDataLogging(); |
|||
} |
|||
}); |
|||
|
|||
// 配置身份认证
|
|||
services |
|||
.AddAuthentication() |
|||
.AddJwtBearer(); |
|||
|
|||
services |
|||
.AddAuthorization(); |
|||
// 配置身份认证服务
|
|||
services |
|||
.AddIdentityCore<AppUser>() |
|||
.AddRoles<AppRole>() |
|||
.AddEntityFrameworkStores<AppDbContext>(); |
|||
|
|||
// 注册工作单元
|
|||
services.AddScoped<IUnitOfWork, UnitOfWork>(); |
|||
|
|||
// 注册仓储
|
|||
services.AddScoped(typeof(ICommandRepository<>), typeof(CommandRepository<>)); |
|||
services.AddScoped(typeof(IQueryRepository<>), typeof(QueryRepository<>)); |
|||
|
|||
// 添加内存缓存
|
|||
services.AddMemoryCache(); |
|||
|
|||
// 注册缓存服务
|
|||
services.AddScoped<ICacheService, CacheService>(); |
|||
|
|||
// 自动注册服务
|
|||
services |
|||
.Scan(action => |
|||
{ |
|||
action |
|||
.FromAssemblies(assembly) |
|||
.AddClasses(false) |
|||
.UsingRegistrationStrategy(RegistrationStrategy.Skip) |
|||
.AsImplementedInterfaces() |
|||
.WithScopedLifetime(); |
|||
}); |
|||
|
|||
return services; |
|||
} |
|||
} |
@ -0,0 +1,166 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using CellularManagement.Infrastructure.Context; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace CellularManagement.Infrastructure.Migrations |
|||
{ |
|||
[DbContext(typeof(AppDbContext))] |
|||
[Migration("20250427103103_InitialCreate")] |
|||
partial class InitialCreate |
|||
{ |
|||
/// <inheritdoc />
|
|||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("ProductVersion", "8.0.0") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 63); |
|||
|
|||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); |
|||
|
|||
modelBuilder.Entity("CellularManagement.Domain.Entities.AppRole", b => |
|||
{ |
|||
b.Property<string>("Id") |
|||
.HasColumnType("text") |
|||
.HasComment("角色ID,主键"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasColumnType("text") |
|||
.HasComment("并发控制戳"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("角色名称"); |
|||
|
|||
b.Property<string>("NormalizedName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化角色名称(大写)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Roles_Name"); |
|||
|
|||
b.HasIndex("NormalizedName") |
|||
.IsUnique() |
|||
.HasDatabaseName("RoleNameIndex"); |
|||
|
|||
b.ToTable("Roles", null, t => |
|||
{ |
|||
t.HasComment("角色表"); |
|||
}); |
|||
}); |
|||
|
|||
modelBuilder.Entity("CellularManagement.Domain.Entities.AppUser", b => |
|||
{ |
|||
b.Property<string>("Id") |
|||
.HasColumnType("text") |
|||
.HasComment("用户ID,主键"); |
|||
|
|||
b.Property<int>("AccessFailedCount") |
|||
.HasColumnType("integer") |
|||
.HasComment("登录失败次数"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasColumnType("text") |
|||
.HasComment("并发控制戳"); |
|||
|
|||
b.Property<string>("Email") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("电子邮箱"); |
|||
|
|||
b.Property<bool>("EmailConfirmed") |
|||
.HasColumnType("boolean") |
|||
.HasComment("邮箱是否已验证"); |
|||
|
|||
b.Property<bool>("LockoutEnabled") |
|||
.HasColumnType("boolean") |
|||
.HasComment("是否启用账户锁定"); |
|||
|
|||
b.Property<DateTimeOffset?>("LockoutEnd") |
|||
.HasColumnType("timestamp with time zone") |
|||
.HasComment("账户锁定结束时间"); |
|||
|
|||
b.Property<string>("NormalizedEmail") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化电子邮箱(大写)"); |
|||
|
|||
b.Property<string>("NormalizedUserName") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化用户名(大写)"); |
|||
|
|||
b.Property<string>("PasswordHash") |
|||
.HasColumnType("text") |
|||
.HasComment("密码哈希值"); |
|||
|
|||
b.Property<string>("PhoneNumber") |
|||
.IsRequired() |
|||
.HasColumnType("text") |
|||
.HasComment("电话号码"); |
|||
|
|||
b.Property<bool>("PhoneNumberConfirmed") |
|||
.HasColumnType("boolean") |
|||
.HasComment("电话号码是否已验证"); |
|||
|
|||
b.Property<string>("SecurityStamp") |
|||
.HasColumnType("text") |
|||
.HasComment("安全戳,用于并发控制"); |
|||
|
|||
b.Property<bool>("TwoFactorEnabled") |
|||
.HasColumnType("boolean") |
|||
.HasComment("是否启用双因素认证"); |
|||
|
|||
b.Property<string>("UserName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("用户名"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Email") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_Email"); |
|||
|
|||
b.HasIndex("NormalizedEmail") |
|||
.HasDatabaseName("EmailIndex"); |
|||
|
|||
b.HasIndex("NormalizedUserName") |
|||
.IsUnique() |
|||
.HasDatabaseName("UserNameIndex"); |
|||
|
|||
b.HasIndex("PhoneNumber") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_PhoneNumber"); |
|||
|
|||
b.HasIndex("UserName") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_UserName"); |
|||
|
|||
b.ToTable("Users", null, t => |
|||
{ |
|||
t.HasComment("用户表"); |
|||
}); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,107 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace CellularManagement.Infrastructure.Migrations |
|||
{ |
|||
/// <inheritdoc />
|
|||
public partial class InitialCreate : Migration |
|||
{ |
|||
/// <inheritdoc />
|
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "Roles", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<string>(type: "text", nullable: false, comment: "角色ID,主键"), |
|||
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false, comment: "角色名称"), |
|||
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false, comment: "标准化角色名称(大写)"), |
|||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true, comment: "并发控制戳") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_Roles", x => x.Id); |
|||
}, |
|||
comment: "角色表"); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "Users", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<string>(type: "text", nullable: false, comment: "用户ID,主键"), |
|||
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false, comment: "用户名"), |
|||
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true, comment: "标准化用户名(大写)"), |
|||
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false, comment: "电子邮箱"), |
|||
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true, comment: "标准化电子邮箱(大写)"), |
|||
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false, comment: "邮箱是否已验证"), |
|||
PasswordHash = table.Column<string>(type: "text", nullable: true, comment: "密码哈希值"), |
|||
SecurityStamp = table.Column<string>(type: "text", nullable: true, comment: "安全戳,用于并发控制"), |
|||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true, comment: "并发控制戳"), |
|||
PhoneNumber = table.Column<string>(type: "text", nullable: false, comment: "电话号码"), |
|||
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false, comment: "电话号码是否已验证"), |
|||
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false, comment: "是否启用双因素认证"), |
|||
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "账户锁定结束时间"), |
|||
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false, comment: "是否启用账户锁定"), |
|||
AccessFailedCount = table.Column<int>(type: "integer", nullable: false, comment: "登录失败次数") |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_Users", x => x.Id); |
|||
}, |
|||
comment: "用户表"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Roles_Name", |
|||
table: "Roles", |
|||
column: "Name", |
|||
unique: true); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "RoleNameIndex", |
|||
table: "Roles", |
|||
column: "NormalizedName", |
|||
unique: true); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "EmailIndex", |
|||
table: "Users", |
|||
column: "NormalizedEmail"); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Users_Email", |
|||
table: "Users", |
|||
column: "Email", |
|||
unique: true); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Users_PhoneNumber", |
|||
table: "Users", |
|||
column: "PhoneNumber", |
|||
unique: true); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_Users_UserName", |
|||
table: "Users", |
|||
column: "UserName", |
|||
unique: true); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "UserNameIndex", |
|||
table: "Users", |
|||
column: "NormalizedUserName", |
|||
unique: true); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "Roles"); |
|||
|
|||
migrationBuilder.DropTable( |
|||
name: "Users"); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,163 @@ |
|||
// <auto-generated />
|
|||
using System; |
|||
using CellularManagement.Infrastructure.Context; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Infrastructure; |
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
|||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; |
|||
|
|||
#nullable disable |
|||
|
|||
namespace CellularManagement.Infrastructure.Migrations |
|||
{ |
|||
[DbContext(typeof(AppDbContext))] |
|||
partial class AppDbContextModelSnapshot : ModelSnapshot |
|||
{ |
|||
protected override void BuildModel(ModelBuilder modelBuilder) |
|||
{ |
|||
#pragma warning disable 612, 618
|
|||
modelBuilder |
|||
.HasAnnotation("ProductVersion", "8.0.0") |
|||
.HasAnnotation("Relational:MaxIdentifierLength", 63); |
|||
|
|||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); |
|||
|
|||
modelBuilder.Entity("CellularManagement.Domain.Entities.AppRole", b => |
|||
{ |
|||
b.Property<string>("Id") |
|||
.HasColumnType("text") |
|||
.HasComment("角色ID,主键"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasColumnType("text") |
|||
.HasComment("并发控制戳"); |
|||
|
|||
b.Property<string>("Name") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("角色名称"); |
|||
|
|||
b.Property<string>("NormalizedName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化角色名称(大写)"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Name") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Roles_Name"); |
|||
|
|||
b.HasIndex("NormalizedName") |
|||
.IsUnique() |
|||
.HasDatabaseName("RoleNameIndex"); |
|||
|
|||
b.ToTable("Roles", null, t => |
|||
{ |
|||
t.HasComment("角色表"); |
|||
}); |
|||
}); |
|||
|
|||
modelBuilder.Entity("CellularManagement.Domain.Entities.AppUser", b => |
|||
{ |
|||
b.Property<string>("Id") |
|||
.HasColumnType("text") |
|||
.HasComment("用户ID,主键"); |
|||
|
|||
b.Property<int>("AccessFailedCount") |
|||
.HasColumnType("integer") |
|||
.HasComment("登录失败次数"); |
|||
|
|||
b.Property<string>("ConcurrencyStamp") |
|||
.IsConcurrencyToken() |
|||
.HasColumnType("text") |
|||
.HasComment("并发控制戳"); |
|||
|
|||
b.Property<string>("Email") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("电子邮箱"); |
|||
|
|||
b.Property<bool>("EmailConfirmed") |
|||
.HasColumnType("boolean") |
|||
.HasComment("邮箱是否已验证"); |
|||
|
|||
b.Property<bool>("LockoutEnabled") |
|||
.HasColumnType("boolean") |
|||
.HasComment("是否启用账户锁定"); |
|||
|
|||
b.Property<DateTimeOffset?>("LockoutEnd") |
|||
.HasColumnType("timestamp with time zone") |
|||
.HasComment("账户锁定结束时间"); |
|||
|
|||
b.Property<string>("NormalizedEmail") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化电子邮箱(大写)"); |
|||
|
|||
b.Property<string>("NormalizedUserName") |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("标准化用户名(大写)"); |
|||
|
|||
b.Property<string>("PasswordHash") |
|||
.HasColumnType("text") |
|||
.HasComment("密码哈希值"); |
|||
|
|||
b.Property<string>("PhoneNumber") |
|||
.IsRequired() |
|||
.HasColumnType("text") |
|||
.HasComment("电话号码"); |
|||
|
|||
b.Property<bool>("PhoneNumberConfirmed") |
|||
.HasColumnType("boolean") |
|||
.HasComment("电话号码是否已验证"); |
|||
|
|||
b.Property<string>("SecurityStamp") |
|||
.HasColumnType("text") |
|||
.HasComment("安全戳,用于并发控制"); |
|||
|
|||
b.Property<bool>("TwoFactorEnabled") |
|||
.HasColumnType("boolean") |
|||
.HasComment("是否启用双因素认证"); |
|||
|
|||
b.Property<string>("UserName") |
|||
.IsRequired() |
|||
.HasMaxLength(256) |
|||
.HasColumnType("character varying(256)") |
|||
.HasComment("用户名"); |
|||
|
|||
b.HasKey("Id"); |
|||
|
|||
b.HasIndex("Email") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_Email"); |
|||
|
|||
b.HasIndex("NormalizedEmail") |
|||
.HasDatabaseName("EmailIndex"); |
|||
|
|||
b.HasIndex("NormalizedUserName") |
|||
.IsUnique() |
|||
.HasDatabaseName("UserNameIndex"); |
|||
|
|||
b.HasIndex("PhoneNumber") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_PhoneNumber"); |
|||
|
|||
b.HasIndex("UserName") |
|||
.IsUnique() |
|||
.HasDatabaseName("IX_Users_UserName"); |
|||
|
|||
b.ToTable("Users", null, t => |
|||
{ |
|||
t.HasComment("用户表"); |
|||
}); |
|||
}); |
|||
#pragma warning restore 612, 618
|
|||
} |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
namespace CellularManagement.Infrastructure.Options; |
|||
|
|||
public class DatabaseOptions |
|||
{ |
|||
public const string SectionName = "DatabaseOptions"; |
|||
|
|||
public string DefaultConnection { get; set; } = string.Empty; |
|||
public int CommandTimeout { get; set; } = 30; |
|||
public bool EnableDetailedErrors { get; set; } = false; |
|||
public bool EnableSensitiveDataLogging { get; set; } = false; |
|||
} |
@ -0,0 +1,112 @@ |
|||
using System.Text; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
|
|||
namespace CellularManagement.Infrastructure.Options; |
|||
|
|||
/// <summary>
|
|||
/// JWT Bearer 认证配置类
|
|||
/// </summary>
|
|||
public class JwtBearerOptionsSetup : IConfigureOptions<JwtBearerOptions> |
|||
{ |
|||
private readonly JwtOptions _jwtOptions; |
|||
private readonly ILogger<JwtBearerOptionsSetup> _logger; |
|||
|
|||
public JwtBearerOptionsSetup( |
|||
IOptions<JwtOptions> jwtOptions, |
|||
ILogger<JwtBearerOptionsSetup> logger) |
|||
{ |
|||
_jwtOptions = jwtOptions.Value; |
|||
_logger = logger; |
|||
|
|||
// 验证密钥强度
|
|||
_jwtOptions.ValidateKeyStrength(); |
|||
} |
|||
|
|||
public void Configure(JwtBearerOptions options) |
|||
{ |
|||
// 创建对称安全密钥
|
|||
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtOptions.SecretKey)); |
|||
|
|||
// 配置令牌验证参数
|
|||
options.TokenValidationParameters = new TokenValidationParameters |
|||
{ |
|||
// 验证颁发者
|
|||
ValidateIssuer = true, |
|||
ValidIssuer = _jwtOptions.Issuer, |
|||
|
|||
// 验证受众
|
|||
ValidateAudience = true, |
|||
ValidAudience = _jwtOptions.Audience, |
|||
|
|||
// 验证过期时间
|
|||
ValidateLifetime = true, |
|||
|
|||
// 设置签名密钥
|
|||
IssuerSigningKey = securityKey, |
|||
ValidateIssuerSigningKey = true, |
|||
|
|||
// 配置时钟偏差
|
|||
ClockSkew = TimeSpan.FromMinutes(_jwtOptions.ClockSkewMinutes), |
|||
|
|||
// 其他安全设置
|
|||
RequireExpirationTime = true, |
|||
RequireSignedTokens = true, |
|||
RequireAudience = true |
|||
}; |
|||
|
|||
// 配置事件处理
|
|||
options.Events = new JwtBearerEvents |
|||
{ |
|||
// 认证失败时记录日志
|
|||
OnAuthenticationFailed = context => |
|||
{ |
|||
_logger.LogError(context.Exception, "JWT 认证失败: {Message}", context.Exception?.Message); |
|||
return Task.CompletedTask; |
|||
}, |
|||
|
|||
// 令牌验证成功时
|
|||
OnTokenValidated = context => |
|||
{ |
|||
var claimsIdentity = context.Principal?.Identity as System.Security.Claims.ClaimsIdentity; |
|||
if (claimsIdentity == null) |
|||
{ |
|||
context.Fail("无效的身份声明"); |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
_logger.LogInformation("JWT 令牌验证成功: {Subject}", |
|||
claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value); |
|||
return Task.CompletedTask; |
|||
}, |
|||
|
|||
// 消息接收时
|
|||
OnMessageReceived = context => |
|||
{ |
|||
// 从查询字符串中获取令牌
|
|||
var accessToken = context.Request.Query["access_token"]; |
|||
if (!string.IsNullOrEmpty(accessToken)) |
|||
{ |
|||
context.Token = accessToken; |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
}, |
|||
|
|||
// 质询时
|
|||
OnChallenge = context => |
|||
{ |
|||
_logger.LogWarning("JWT 质询: {Error}", context.Error); |
|||
return Task.CompletedTask; |
|||
} |
|||
}; |
|||
|
|||
// 强制使用 HTTPS
|
|||
options.RequireHttpsMetadata = true; |
|||
|
|||
// 不保存令牌
|
|||
options.SaveToken = false; |
|||
} |
|||
} |
@ -0,0 +1,215 @@ |
|||
using System.Text; |
|||
using Microsoft.AspNetCore.Authentication.JwtBearer; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
|
|||
namespace CellularManagement.Infrastructure.Options; |
|||
|
|||
/// <summary>
|
|||
/// JWT 配置选项
|
|||
/// 用于配置 JWT 认证相关的参数
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 设计说明:
|
|||
/// 1. 使用强类型配置,避免魔法字符串
|
|||
/// 2. 支持从配置文件加载
|
|||
/// 3. 提供合理的默认值
|
|||
/// 4. 支持密钥轮换
|
|||
/// 5. 强制使用 HTTPS
|
|||
/// 6. 启用所有安全验证
|
|||
/// </remarks>
|
|||
public class JwtOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 配置节点名称
|
|||
/// </summary>
|
|||
public const string SectionName = "JwtOptions"; |
|||
|
|||
/// <summary>
|
|||
/// 当前使用的密钥
|
|||
/// 用于签名和验证 JWT 令牌
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 使用至少 32 字节的随机字符串
|
|||
/// 2. 定期轮换密钥
|
|||
/// 3. 不要将密钥硬编码在代码中
|
|||
/// 4. 使用环境变量或密钥管理服务存储
|
|||
/// </remarks>
|
|||
public string SecretKey { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// 密钥轮换间隔(天)
|
|||
/// </summary>
|
|||
public int KeyRotationDays { get; set; } = 30; |
|||
|
|||
/// <summary>
|
|||
/// 密钥最小长度
|
|||
/// </summary>
|
|||
public int MinKeyLength { get; set; } = 32; |
|||
|
|||
/// <summary>
|
|||
/// 颁发者
|
|||
/// 标识 JWT 的签发者
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 使用有意义的标识符
|
|||
/// 2. 可以是域名或服务名称
|
|||
/// 3. 用于验证令牌来源
|
|||
/// </remarks>
|
|||
public string Issuer { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// 受众
|
|||
/// 标识 JWT 的接收者
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 使用有意义的标识符
|
|||
/// 2. 可以是服务名称或客户端标识
|
|||
/// 3. 用于验证令牌目标
|
|||
/// </remarks>
|
|||
public string Audience { get; set; } = string.Empty; |
|||
|
|||
/// <summary>
|
|||
/// 访问令牌过期时间(分钟)
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 根据安全需求设置合适的过期时间
|
|||
/// 2. 通常设置为 15-60 分钟
|
|||
/// 3. 使用刷新令牌机制延长会话
|
|||
/// </remarks>
|
|||
public int ExpiryMinutes { get; set; } = 15; // 缩短默认过期时间
|
|||
|
|||
/// <summary>
|
|||
/// 刷新令牌过期时间(天)
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 设置较长的过期时间
|
|||
/// 2. 通常设置为 7-30 天
|
|||
/// 3. 支持用户保持登录状态
|
|||
/// </remarks>
|
|||
public int RefreshTokenExpiryDays { get; set; } = 7; |
|||
|
|||
/// <summary>
|
|||
/// 是否验证颁发者
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 生产环境应该启用
|
|||
/// 2. 开发环境可以禁用
|
|||
/// 3. 用于防止令牌伪造
|
|||
/// </remarks>
|
|||
public bool ValidateIssuer { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// 是否验证受众
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 生产环境应该启用
|
|||
/// 2. 开发环境可以禁用
|
|||
/// 3. 用于防止令牌滥用
|
|||
/// </remarks>
|
|||
public bool ValidateAudience { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// 是否验证过期时间
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 始终启用
|
|||
/// 2. 确保令牌不会永久有效
|
|||
/// 3. 提高安全性
|
|||
/// </remarks>
|
|||
public bool ValidateLifetime { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// 时钟偏差(分钟)
|
|||
/// 允许的服务器时间偏差
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 设置合理的偏差值
|
|||
/// 2. 通常设置为 5 分钟
|
|||
/// 3. 用于处理服务器时间不同步的情况
|
|||
/// </remarks>
|
|||
public int ClockSkewMinutes { get; set; } = 5; |
|||
|
|||
/// <summary>
|
|||
/// 是否要求 HTTPS
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 生产环境应该启用
|
|||
/// 2. 开发环境可以禁用
|
|||
/// 3. 确保令牌传输安全
|
|||
/// </remarks>
|
|||
public bool RequireHttpsMetadata { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// 是否保存令牌
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 建议:
|
|||
/// 1. 通常禁用
|
|||
/// 2. 用于调试目的
|
|||
/// 3. 生产环境应该禁用
|
|||
/// </remarks>
|
|||
public bool SaveToken { get; set; } = false; |
|||
|
|||
/// <summary>
|
|||
/// 验证密钥强度
|
|||
/// </summary>
|
|||
public void ValidateKeyStrength() |
|||
{ |
|||
if (string.IsNullOrEmpty(SecretKey)) |
|||
{ |
|||
throw new ArgumentException("JWT 密钥不能为空"); |
|||
} |
|||
|
|||
if (SecretKey.Length < MinKeyLength) |
|||
{ |
|||
throw new ArgumentException($"JWT 密钥长度必须至少为 {MinKeyLength} 字节"); |
|||
} |
|||
|
|||
// 检查密钥是否包含足够的随机性
|
|||
var entropy = CalculateEntropy(SecretKey); |
|||
if (entropy < 3.5) // 3.5 bits per character is considered good
|
|||
{ |
|||
throw new ArgumentException("JWT 密钥随机性不足"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 计算字符串的熵
|
|||
/// </summary>
|
|||
private static double CalculateEntropy(string input) |
|||
{ |
|||
var frequencies = new Dictionary<char, int>(); |
|||
foreach (var c in input) |
|||
{ |
|||
if (frequencies.ContainsKey(c)) |
|||
{ |
|||
frequencies[c]++; |
|||
} |
|||
else |
|||
{ |
|||
frequencies[c] = 1; |
|||
} |
|||
} |
|||
|
|||
var length = input.Length; |
|||
var entropy = 0.0; |
|||
foreach (var frequency in frequencies.Values) |
|||
{ |
|||
var probability = (double)frequency / length; |
|||
entropy -= probability * Math.Log2(probability); |
|||
} |
|||
|
|||
return entropy; |
|||
} |
|||
} |
@ -0,0 +1,208 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using CellularManagement.Domain.Repositories; |
|||
using CellularManagement.Infrastructure.Context; |
|||
using System.Linq.Expressions; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace CellularManagement.Infrastructure.Repositories; |
|||
|
|||
/// <summary>
|
|||
/// 命令仓储实现类
|
|||
/// 实现了 ICommandRepository 接口,提供数据写入操作的具体实现
|
|||
/// </summary>
|
|||
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 使用 Entity Framework Core 作为 ORM
|
|||
/// 2. 通过 UnitOfWork 管理事务
|
|||
/// 3. 使用日志记录器记录错误信息
|
|||
/// 4. 实现了同步和异步操作的分离
|
|||
/// </remarks>
|
|||
public class CommandRepository<T> : ICommandRepository<T> where T : class |
|||
{ |
|||
/// <summary>
|
|||
/// 数据库上下文
|
|||
/// </summary>
|
|||
protected readonly AppDbContext _context; |
|||
|
|||
/// <summary>
|
|||
/// 实体集合
|
|||
/// </summary>
|
|||
protected readonly DbSet<T> _dbSet; |
|||
|
|||
/// <summary>
|
|||
/// 工作单元,用于管理事务
|
|||
/// </summary>
|
|||
protected readonly IUnitOfWork _unitOfWork; |
|||
|
|||
/// <summary>
|
|||
/// 日志记录器
|
|||
/// </summary>
|
|||
protected readonly ILogger<CommandRepository<T>> _logger; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
/// <param name="context">数据库上下文</param>
|
|||
/// <param name="unitOfWork">工作单元</param>
|
|||
/// <param name="logger">日志记录器</param>
|
|||
public CommandRepository( |
|||
AppDbContext context, |
|||
IUnitOfWork unitOfWork, |
|||
ILogger<CommandRepository<T>> logger) |
|||
{ |
|||
_context = context; |
|||
_dbSet = context.Set<T>(); |
|||
_unitOfWork = unitOfWork; |
|||
_logger = logger; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 添加单个实体到数据库
|
|||
/// </summary>
|
|||
/// <param name="entity">要添加的实体</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>添加后的实体</returns>
|
|||
/// <remarks>
|
|||
/// 使用 AddAsync 方法将实体添加到数据库上下文中
|
|||
/// 实体将在事务提交时保存到数据库
|
|||
/// </remarks>
|
|||
public async Task<T> AddAsync(T entity, CancellationToken cancellationToken = default) |
|||
{ |
|||
await _dbSet.AddAsync(entity, cancellationToken); |
|||
return entity; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 批量添加多个实体到数据库
|
|||
/// </summary>
|
|||
/// <param name="entities">要添加的实体集合</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>添加后的实体集合</returns>
|
|||
/// <remarks>
|
|||
/// 如果实体集合为空,直接返回
|
|||
/// 使用 AddRangeAsync 方法批量添加实体
|
|||
/// 批量添加比逐个添加更高效
|
|||
/// </remarks>
|
|||
public async Task<IEnumerable<T>> AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default) |
|||
{ |
|||
if (!entities.Any()) |
|||
{ |
|||
return entities; |
|||
} |
|||
|
|||
await _dbSet.AddRangeAsync(entities, cancellationToken); |
|||
return entities; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 更新单个实体的状态
|
|||
/// </summary>
|
|||
/// <param name="entity">要更新的实体</param>
|
|||
/// <remarks>
|
|||
/// 使用 Update 方法标记实体状态为已修改
|
|||
/// 实际的数据库更新操作将在事务提交时执行
|
|||
/// </remarks>
|
|||
public void Update(T entity) |
|||
{ |
|||
_dbSet.Update(entity); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 批量更新多个实体的状态
|
|||
/// </summary>
|
|||
/// <param name="entities">要更新的实体集合</param>
|
|||
/// <remarks>
|
|||
/// 如果实体集合为空,直接返回
|
|||
/// 使用 UpdateRange 方法批量标记实体状态
|
|||
/// 批量更新比逐个更新更高效
|
|||
/// </remarks>
|
|||
public void UpdateRange(IEnumerable<T> entities) |
|||
{ |
|||
if (!entities.Any()) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
_dbSet.UpdateRange(entities); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 删除单个实体
|
|||
/// </summary>
|
|||
/// <param name="entity">要删除的实体</param>
|
|||
/// <remarks>
|
|||
/// 使用 Remove 方法标记实体状态为已删除
|
|||
/// 实际的数据库删除操作将在事务提交时执行
|
|||
/// </remarks>
|
|||
public void Delete(T entity) |
|||
{ |
|||
_dbSet.Remove(entity); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 批量删除多个实体
|
|||
/// </summary>
|
|||
/// <param name="entities">要删除的实体集合</param>
|
|||
/// <remarks>
|
|||
/// 如果实体集合为空,直接返回
|
|||
/// 使用 RemoveRange 方法批量标记实体状态
|
|||
/// 批量删除比逐个删除更高效
|
|||
/// </remarks>
|
|||
public void DeleteRange(IEnumerable<T> entities) |
|||
{ |
|||
if (!entities.Any()) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
_dbSet.RemoveRange(entities); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据ID删除实体
|
|||
/// </summary>
|
|||
/// <param name="id">要删除的实体的ID</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>是否成功找到并删除实体</returns>
|
|||
/// <remarks>
|
|||
/// 首先通过ID查找实体
|
|||
/// 如果实体不存在,返回 false
|
|||
/// 如果实体存在,将其标记为已删除
|
|||
/// </remarks>
|
|||
public async Task<bool> DeleteByIdAsync(string id, CancellationToken cancellationToken = default) |
|||
{ |
|||
var entity = await _dbSet.FindAsync(new object[] { id }, cancellationToken); |
|||
if (entity == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
_dbSet.Remove(entity); |
|||
return true; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据条件删除实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">删除条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>删除的实体数量</returns>
|
|||
/// <remarks>
|
|||
/// 使用 LINQ 表达式树构建查询条件
|
|||
/// 先查询符合条件的实体
|
|||
/// 如果找到实体,批量标记为已删除
|
|||
/// 返回实际删除的实体数量
|
|||
/// </remarks>
|
|||
public async Task<int> DeleteWhereAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default) |
|||
{ |
|||
var entities = await _dbSet.Where(predicate).ToListAsync(cancellationToken); |
|||
if (!entities.Any()) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
_dbSet.RemoveRange(entities); |
|||
return entities.Count; |
|||
} |
|||
} |
@ -0,0 +1,195 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using System.Linq.Expressions; |
|||
using CellularManagement.Domain.Repositories; |
|||
using CellularManagement.Infrastructure.Context; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace CellularManagement.Infrastructure.Repositories; |
|||
|
|||
/// <summary>
|
|||
/// 查询仓储实现类
|
|||
/// 实现了 IQueryRepository 接口,提供数据读取操作的具体实现
|
|||
/// </summary>
|
|||
/// <typeparam name="T">实体类型,必须是引用类型</typeparam>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 使用 Entity Framework Core 作为 ORM
|
|||
/// 2. 所有查询操作都是异步的,以提高性能
|
|||
/// 3. 支持 LINQ 表达式树构建复杂查询
|
|||
/// 4. 实现了分页查询,优化大数据量查询性能
|
|||
/// </remarks>
|
|||
public class QueryRepository<T> : IQueryRepository<T> where T : class |
|||
{ |
|||
/// <summary>
|
|||
/// 数据库上下文
|
|||
/// </summary>
|
|||
protected readonly AppDbContext _context; |
|||
|
|||
/// <summary>
|
|||
/// 实体集合
|
|||
/// </summary>
|
|||
protected readonly DbSet<T> _dbSet; |
|||
|
|||
/// <summary>
|
|||
/// 日志记录器
|
|||
/// </summary>
|
|||
protected readonly ILogger<QueryRepository<T>> _logger; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
/// <param name="context">数据库上下文</param>
|
|||
/// <param name="logger">日志记录器</param>
|
|||
public QueryRepository( |
|||
AppDbContext context, |
|||
ILogger<QueryRepository<T>> logger) |
|||
{ |
|||
_context = context; |
|||
_dbSet = context.Set<T>(); |
|||
_logger = logger; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据ID查询单个实体
|
|||
/// </summary>
|
|||
/// <param name="id">要查询的实体ID</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>查询到的实体,如果不存在则返回 null</returns>
|
|||
/// <remarks>
|
|||
/// 使用 FindAsync 方法通过主键查询,性能最优
|
|||
/// 如果实体不存在,返回 null
|
|||
/// </remarks>
|
|||
public async Task<T?> GetByIdAsync(string id, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.FindAsync(new object[] { id }, cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查询所有实体
|
|||
/// </summary>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>所有实体的集合</returns>
|
|||
/// <remarks>
|
|||
/// 使用 ToListAsync 方法异步获取所有实体
|
|||
/// 注意:对于大数据量的表,建议使用分页查询
|
|||
/// </remarks>
|
|||
public async Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.ToListAsync(cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据条件查询实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>符合条件的实体集合</returns>
|
|||
/// <remarks>
|
|||
/// 使用 Where 方法构建查询条件
|
|||
/// 使用 ToListAsync 方法异步获取结果
|
|||
/// 条件查询会被转换为 SQL 语句在数据库端执行
|
|||
/// </remarks>
|
|||
public async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.Where(predicate).ToListAsync(cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 分页查询实体
|
|||
/// </summary>
|
|||
/// <param name="pageNumber">页码,从1开始</param>
|
|||
/// <param name="pageSize">每页记录数</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
|
|||
/// <remarks>
|
|||
/// 先获取总记录数
|
|||
/// 使用 Skip 和 Take 方法实现分页
|
|||
/// 分页查询可以有效减少数据传输量,提高性能
|
|||
/// </remarks>
|
|||
public async Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync(int pageNumber, int pageSize, CancellationToken cancellationToken = default) |
|||
{ |
|||
var totalCount = await _dbSet.CountAsync(cancellationToken); |
|||
var items = await _dbSet |
|||
.Skip((pageNumber - 1) * pageSize) |
|||
.Take(pageSize) |
|||
.ToListAsync(cancellationToken); |
|||
|
|||
return (totalCount, items); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据条件分页查询实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="pageNumber">页码,从1开始</param>
|
|||
/// <param name="pageSize">每页记录数</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>分页查询结果,包含总记录数和当前页数据</returns>
|
|||
/// <remarks>
|
|||
/// 先根据条件获取总记录数
|
|||
/// 使用 Where 方法构建查询条件
|
|||
/// 使用 Skip 和 Take 方法实现分页
|
|||
/// 结合条件查询和分页查询,适用于大数据量的条件筛选
|
|||
/// </remarks>
|
|||
public async Task<(int TotalCount, IEnumerable<T> Items)> GetPagedAsync( |
|||
Expression<Func<T, bool>> predicate, |
|||
int pageNumber, |
|||
int pageSize, |
|||
CancellationToken cancellationToken = default) |
|||
{ |
|||
var query = _dbSet.Where(predicate); |
|||
var totalCount = await query.CountAsync(cancellationToken); |
|||
var items = await query |
|||
.Skip((pageNumber - 1) * pageSize) |
|||
.Take(pageSize) |
|||
.ToListAsync(cancellationToken); |
|||
|
|||
return (totalCount, items); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查询单个实体
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>查询到的实体,如果不存在则返回 null</returns>
|
|||
/// <remarks>
|
|||
/// 使用 FirstOrDefaultAsync 方法获取第一个符合条件的实体
|
|||
/// 如果查询结果包含多个实体,将返回第一个
|
|||
/// 建议在确定只会返回一个结果时使用
|
|||
/// </remarks>
|
|||
public async Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.FirstOrDefaultAsync(predicate, cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 查询实体是否存在
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>是否存在符合条件的实体</returns>
|
|||
/// <remarks>
|
|||
/// 使用 AnyAsync 方法检查是否存在符合条件的实体
|
|||
/// 使用 EXISTS 语句在数据库端执行,性能优于获取完整实体
|
|||
/// </remarks>
|
|||
public async Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.AnyAsync(predicate, cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 统计符合条件的实体数量
|
|||
/// </summary>
|
|||
/// <param name="predicate">查询条件表达式</param>
|
|||
/// <param name="cancellationToken">取消令牌</param>
|
|||
/// <returns>符合条件的实体数量</returns>
|
|||
/// <remarks>
|
|||
/// 使用 CountAsync 方法统计符合条件的实体数量
|
|||
/// 使用 COUNT 语句在数据库端执行,性能优于获取完整实体
|
|||
/// </remarks>
|
|||
public async Task<int> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await _dbSet.CountAsync(predicate, cancellationToken); |
|||
} |
|||
} |
@ -0,0 +1,64 @@ |
|||
using CellularManagement.Application.Services; |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
|
|||
namespace CellularManagement.Infrastructure.Services; |
|||
|
|||
/// <summary>
|
|||
/// 内存缓存服务实现
|
|||
/// </summary>
|
|||
public sealed class CacheService : ICacheService |
|||
{ |
|||
private readonly IMemoryCache _memoryCache; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
/// <param name="memoryCache">内存缓存</param>
|
|||
public CacheService(IMemoryCache memoryCache) |
|||
{ |
|||
_memoryCache = memoryCache; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public T? Get<T>(string key) |
|||
{ |
|||
return _memoryCache.Get<T>(key); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public void Set<T>(string key, T value, MemoryCacheEntryOptions? options = null) |
|||
{ |
|||
if (options == null) |
|||
{ |
|||
options = new MemoryCacheEntryOptions() |
|||
.SetSlidingExpiration(TimeSpan.FromMinutes(30)) |
|||
.SetAbsoluteExpiration(TimeSpan.FromHours(1)); |
|||
} |
|||
|
|||
_memoryCache.Set(key, value, options); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public bool TryAdd<T>(string key, T value, MemoryCacheEntryOptions options) |
|||
{ |
|||
if (_memoryCache.TryGetValue(key, out _)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
_memoryCache.Set(key, value, options); |
|||
return true; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public void Remove(string key) |
|||
{ |
|||
_memoryCache.Remove(key); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public bool TryGetValue<T>(string key, out T? value) |
|||
{ |
|||
return _memoryCache.TryGetValue(key, out value); |
|||
} |
|||
} |
@ -0,0 +1,378 @@ |
|||
using System.IdentityModel.Tokens.Jwt; |
|||
using System.Security.Claims; |
|||
using System.Text; |
|||
using CellularManagement.Application.Services; |
|||
using CellularManagement.Infrastructure.Options; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Tokens; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
|
|||
namespace CellularManagement.Infrastructure.Services; |
|||
|
|||
/// <summary>
|
|||
/// JWT 令牌提供者实现
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 实现说明:
|
|||
/// 1. 使用 JwtOptions 配置生成和验证令牌
|
|||
/// 2. 支持访问令牌和刷新令牌
|
|||
/// 3. 提供完整的令牌验证和解析功能
|
|||
/// 4. 强制使用强密钥
|
|||
/// 5. 支持密钥轮换
|
|||
/// 6. 支持令牌撤销和黑名单
|
|||
/// </remarks>
|
|||
public sealed class JwtProvider : IJwtProvider |
|||
{ |
|||
private readonly JwtOptions _jwtOptions; |
|||
private readonly JwtSecurityTokenHandler _tokenHandler; |
|||
private readonly ILogger<JwtProvider> _logger; |
|||
private readonly IKeyRotationService _keyRotationService; |
|||
private readonly ICacheService _cacheService; |
|||
private const string RevokedTokensCacheKey = "RevokedTokens_"; |
|||
private const string TokenBlacklistCacheKey = "TokenBlacklist_"; |
|||
private const string KeyCacheKey = "JwtKey_"; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
/// <param name="jwtOptions">JWT 配置选项</param>
|
|||
/// <param name="logger">日志记录器</param>
|
|||
/// <param name="keyRotationService">密钥轮换服务</param>
|
|||
/// <param name="cacheService">缓存服务</param>
|
|||
public JwtProvider( |
|||
IOptions<JwtOptions> jwtOptions, |
|||
ILogger<JwtProvider> logger, |
|||
IKeyRotationService keyRotationService, |
|||
ICacheService cacheService) |
|||
{ |
|||
_jwtOptions = jwtOptions.Value; |
|||
_tokenHandler = new JwtSecurityTokenHandler(); |
|||
_logger = logger; |
|||
_keyRotationService = keyRotationService; |
|||
_cacheService = cacheService; |
|||
|
|||
// 验证密钥强度
|
|||
_jwtOptions.ValidateKeyStrength(); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string GenerateAccessToken(IEnumerable<Claim> claims) |
|||
{ |
|||
return GenerateToken(claims, _jwtOptions.ExpiryMinutes, "access_token"); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string GenerateRefreshToken(IEnumerable<Claim> claims) |
|||
{ |
|||
return GenerateToken(claims, _jwtOptions.RefreshTokenExpiryDays * 24 * 60, "refresh_token"); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public bool ValidateToken(string token) |
|||
{ |
|||
try |
|||
{ |
|||
// 检查令牌是否被撤销
|
|||
if (IsTokenRevoked(token)) |
|||
{ |
|||
_logger.LogWarning("令牌已被撤销: {Token}", token); |
|||
return false; |
|||
} |
|||
|
|||
// 检查令牌是否在黑名单中
|
|||
if (IsTokenBlacklisted(token)) |
|||
{ |
|||
_logger.LogWarning("令牌在黑名单中: {Token}", token); |
|||
return false; |
|||
} |
|||
|
|||
// 检查是否需要轮换密钥
|
|||
if (_keyRotationService.ShouldRotateKey()) |
|||
{ |
|||
_logger.LogWarning("检测到密钥需要轮换"); |
|||
} |
|||
|
|||
var tokenValidationParameters = new TokenValidationParameters |
|||
{ |
|||
ValidateIssuer = true, |
|||
ValidIssuer = _jwtOptions.Issuer, |
|||
ValidateAudience = true, |
|||
ValidAudience = _jwtOptions.Audience, |
|||
ValidateLifetime = true, |
|||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GetCurrentKey())), |
|||
ValidateIssuerSigningKey = true, |
|||
ClockSkew = TimeSpan.FromMinutes(_jwtOptions.ClockSkewMinutes), |
|||
RequireExpirationTime = true, |
|||
RequireSignedTokens = true, |
|||
RequireAudience = true |
|||
}; |
|||
|
|||
_tokenHandler.ValidateToken(token, tokenValidationParameters, out _); |
|||
return true; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "令牌验证失败: {Message}", ex.Message); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public void RevokeToken(string token) |
|||
{ |
|||
var cacheKey = $"{RevokedTokensCacheKey}{token}"; |
|||
var options = new MemoryCacheEntryOptions() |
|||
.SetAbsoluteExpiration(TimeSpan.FromDays(7)); // 7天后自动清理
|
|||
|
|||
_cacheService.Set(cacheKey, true, options); |
|||
_logger.LogInformation("令牌已被撤销: {Token}", token); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public void AddToBlacklist(string token) |
|||
{ |
|||
var cacheKey = $"{TokenBlacklistCacheKey}{token}"; |
|||
var options = new MemoryCacheEntryOptions() |
|||
.SetAbsoluteExpiration(TimeSpan.FromDays(30)); // 30天后自动清理
|
|||
|
|||
_cacheService.Set(cacheKey, true, options); |
|||
_logger.LogInformation("令牌已添加到黑名单: {Token}", token); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public IEnumerable<Claim> GetClaimsFromToken(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Claims; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌声明失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public DateTime GetTokenExpiration(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.ValidTo; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌过期时间失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public DateTime GetTokenIssuedAt(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.IssuedAt; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌颁发时间失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenSubject(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Subject; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌主题失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenIssuer(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Issuer; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌颁发者失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenAudience(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Audiences.FirstOrDefault(); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌受众失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenAlgorithm(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.SignatureAlgorithm; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌算法失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenType(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Header.Typ; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌类型失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string? GetTokenId(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Id; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取令牌ID失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public IDictionary<string, string> GetAllClaims(string token) |
|||
{ |
|||
try |
|||
{ |
|||
var jwtToken = _tokenHandler.ReadJwtToken(token); |
|||
return jwtToken.Claims.ToDictionary(c => c.Type, c => c.Value); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "获取所有声明失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 生成 JWT 令牌
|
|||
/// </summary>
|
|||
/// <param name="claims">用户声明</param>
|
|||
/// <param name="expiryMinutes">过期时间(分钟)</param>
|
|||
/// <param name="tokenType">令牌类型</param>
|
|||
/// <returns>生成的令牌</returns>
|
|||
private string GenerateToken(IEnumerable<Claim> claims, int expiryMinutes, string tokenType) |
|||
{ |
|||
try |
|||
{ |
|||
// 检查是否需要轮换密钥
|
|||
if (_keyRotationService.ShouldRotateKey()) |
|||
{ |
|||
_logger.LogWarning("检测到密钥需要轮换"); |
|||
} |
|||
|
|||
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GetCurrentKey())); |
|||
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha512); |
|||
|
|||
var tokenDescriptor = new SecurityTokenDescriptor |
|||
{ |
|||
Subject = new ClaimsIdentity(claims), |
|||
Expires = DateTime.UtcNow.AddMinutes(expiryMinutes), |
|||
Issuer = _jwtOptions.Issuer, |
|||
Audience = _jwtOptions.Audience, |
|||
SigningCredentials = credentials, |
|||
IssuedAt = DateTime.UtcNow, |
|||
NotBefore = DateTime.UtcNow |
|||
}; |
|||
|
|||
// 添加令牌类型声明
|
|||
tokenDescriptor.Subject.AddClaim(new Claim("token_type", tokenType)); |
|||
|
|||
var token = _tokenHandler.CreateToken(tokenDescriptor); |
|||
return _tokenHandler.WriteToken(token); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "生成令牌失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 获取当前密钥
|
|||
/// </summary>
|
|||
/// <returns>当前密钥</returns>
|
|||
private string GetCurrentKey() |
|||
{ |
|||
var cacheKey = $"{KeyCacheKey}Current"; |
|||
if (_cacheService.TryGetValue<string>(cacheKey, out var cachedKey)) |
|||
{ |
|||
return cachedKey!; |
|||
} |
|||
|
|||
var currentKey = _keyRotationService.GetCurrentKey(); |
|||
var options = new MemoryCacheEntryOptions() |
|||
.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); // 缓存5分钟
|
|||
|
|||
_cacheService.Set(cacheKey, currentKey, options); |
|||
return currentKey; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 检查令牌是否被撤销
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>是否被撤销</returns>
|
|||
private bool IsTokenRevoked(string token) |
|||
{ |
|||
var cacheKey = $"{RevokedTokensCacheKey}{token}"; |
|||
return _cacheService.TryGetValue<bool>(cacheKey, out _); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 检查令牌是否在黑名单中
|
|||
/// </summary>
|
|||
/// <param name="token">令牌</param>
|
|||
/// <returns>是否在黑名单中</returns>
|
|||
private bool IsTokenBlacklisted(string token) |
|||
{ |
|||
var cacheKey = $"{TokenBlacklistCacheKey}{token}"; |
|||
return _cacheService.TryGetValue<bool>(cacheKey, out _); |
|||
} |
|||
} |
@ -0,0 +1,66 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using CellularManagement.Application.Services; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace CellularManagement.Infrastructure.Services; |
|||
|
|||
/// <summary>
|
|||
/// 密钥轮换后台服务
|
|||
/// </summary>
|
|||
public sealed class KeyRotationBackgroundService : BackgroundService |
|||
{ |
|||
private readonly IKeyRotationService _keyRotationService; |
|||
private readonly ILogger<KeyRotationBackgroundService> _logger; |
|||
private readonly TimeSpan _checkInterval; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
public KeyRotationBackgroundService( |
|||
IKeyRotationService keyRotationService, |
|||
ILogger<KeyRotationBackgroundService> logger) |
|||
{ |
|||
_keyRotationService = keyRotationService; |
|||
_logger = logger; |
|||
_checkInterval = TimeSpan.FromHours(1); // 每小时检查一次
|
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) |
|||
{ |
|||
try |
|||
{ |
|||
// 初始化密钥轮换服务
|
|||
await _keyRotationService.InitializeAsync(); |
|||
|
|||
while (!stoppingToken.IsCancellationRequested) |
|||
{ |
|||
try |
|||
{ |
|||
// 检查是否需要轮换密钥
|
|||
if (_keyRotationService.ShouldRotateKey()) |
|||
{ |
|||
_logger.LogInformation("开始轮换密钥"); |
|||
await _keyRotationService.RotateKeyAsync(); |
|||
_logger.LogInformation("密钥轮换完成"); |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "密钥轮换检查失败: {Message}", ex.Message); |
|||
} |
|||
|
|||
// 等待下一次检查
|
|||
await Task.Delay(_checkInterval, stoppingToken); |
|||
} |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "密钥轮换后台服务失败: {Message}", ex.Message); |
|||
throw; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,164 @@ |
|||
using System; |
|||
using System.Security.Cryptography; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using CellularManagement.Application.Services; |
|||
using CellularManagement.Infrastructure.Options; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.Extensions.Logging; |
|||
|
|||
namespace CellularManagement.Infrastructure.Services; |
|||
|
|||
/// <summary>
|
|||
/// 密钥轮换服务实现
|
|||
/// </summary>
|
|||
public sealed class KeyRotationService : IKeyRotationService |
|||
{ |
|||
private readonly JwtOptions _jwtOptions; |
|||
private readonly ILogger<KeyRotationService> _logger; |
|||
private string _currentKey; |
|||
private string _nextKey; |
|||
private DateTime _lastRotationTime; |
|||
|
|||
/// <summary>
|
|||
/// 构造函数
|
|||
/// </summary>
|
|||
public KeyRotationService(IOptions<JwtOptions> jwtOptions, ILogger<KeyRotationService> logger) |
|||
{ |
|||
_jwtOptions = jwtOptions.Value; |
|||
_logger = logger; |
|||
_currentKey = _jwtOptions.SecretKey; |
|||
_nextKey = GenerateNewKey(); |
|||
_lastRotationTime = DateTime.UtcNow; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public async Task InitializeAsync() |
|||
{ |
|||
try |
|||
{ |
|||
// 验证当前密钥强度
|
|||
ValidateKeyStrength(_currentKey); |
|||
|
|||
// 如果当前密钥即将过期,立即轮换
|
|||
if (ShouldRotateKey()) |
|||
{ |
|||
await RotateKeyAsync(); |
|||
} |
|||
|
|||
_logger.LogInformation("密钥轮换服务初始化完成"); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "密钥轮换服务初始化失败"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string GetCurrentKey() |
|||
{ |
|||
return _currentKey; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public string GetNextKey() |
|||
{ |
|||
return _nextKey; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public async Task RotateKeyAsync() |
|||
{ |
|||
try |
|||
{ |
|||
// 验证新密钥强度
|
|||
ValidateKeyStrength(_nextKey); |
|||
|
|||
// 更新密钥
|
|||
_currentKey = _nextKey; |
|||
_nextKey = GenerateNewKey(); |
|||
_lastRotationTime = DateTime.UtcNow; |
|||
|
|||
// 更新配置
|
|||
_jwtOptions.SecretKey = _currentKey; |
|||
await Task.CompletedTask; |
|||
_logger.LogInformation("密钥轮换完成"); |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
_logger.LogError(ex, "密钥轮换失败"); |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public bool ShouldRotateKey() |
|||
{ |
|||
var timeSinceLastRotation = DateTime.UtcNow - _lastRotationTime; |
|||
return timeSinceLastRotation.TotalDays >= _jwtOptions.KeyRotationDays; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 生成新的密钥
|
|||
/// </summary>
|
|||
private string GenerateNewKey() |
|||
{ |
|||
using var rng = RandomNumberGenerator.Create(); |
|||
var keyBytes = new byte[_jwtOptions.MinKeyLength]; |
|||
rng.GetBytes(keyBytes); |
|||
return Convert.ToBase64String(keyBytes); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 验证密钥强度
|
|||
/// </summary>
|
|||
private void ValidateKeyStrength(string key) |
|||
{ |
|||
if (string.IsNullOrEmpty(key)) |
|||
{ |
|||
throw new ArgumentException("密钥不能为空"); |
|||
} |
|||
|
|||
if (key.Length < _jwtOptions.MinKeyLength) |
|||
{ |
|||
throw new ArgumentException($"密钥长度必须至少为 {_jwtOptions.MinKeyLength} 字节"); |
|||
} |
|||
|
|||
// 检查密钥是否包含足够的随机性
|
|||
var entropy = CalculateEntropy(key); |
|||
if (entropy < 3.5) // 3.5 bits per character is considered good
|
|||
{ |
|||
throw new ArgumentException("密钥随机性不足"); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 计算字符串的熵
|
|||
/// </summary>
|
|||
private static double CalculateEntropy(string input) |
|||
{ |
|||
var frequencies = new Dictionary<char, int>(); |
|||
foreach (var c in input) |
|||
{ |
|||
if (frequencies.ContainsKey(c)) |
|||
{ |
|||
frequencies[c]++; |
|||
} |
|||
else |
|||
{ |
|||
frequencies[c] = 1; |
|||
} |
|||
} |
|||
|
|||
var length = input.Length; |
|||
var entropy = 0.0; |
|||
foreach (var frequency in frequencies.Values) |
|||
{ |
|||
var probability = (double)frequency / length; |
|||
entropy -= probability * Math.Log2(probability); |
|||
} |
|||
|
|||
return entropy; |
|||
} |
|||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Binary file not shown.
Binary file not shown.
@ -0,0 +1,19 @@ |
|||
{ |
|||
"runtimeOptions": { |
|||
"tfm": "net8.0", |
|||
"frameworks": [ |
|||
{ |
|||
"name": "Microsoft.NETCore.App", |
|||
"version": "8.0.0" |
|||
}, |
|||
{ |
|||
"name": "Microsoft.AspNetCore.App", |
|||
"version": "8.0.0" |
|||
} |
|||
], |
|||
"configProperties": { |
|||
"System.Reflection.NullabilityInfoContext.IsSupported": true, |
|||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,28 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Target Name="GetEFProjectMetadata"> |
|||
<MSBuild Condition=" '$(TargetFramework)' == '' " |
|||
Projects="$(MSBuildProjectFile)" |
|||
Targets="GetEFProjectMetadata" |
|||
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" /> |
|||
<ItemGroup Condition=" '$(TargetFramework)' != '' "> |
|||
<EFProjectMetadata Include="AssemblyName: $(AssemblyName)" /> |
|||
<EFProjectMetadata Include="Language: $(Language)" /> |
|||
<EFProjectMetadata Include="OutputPath: $(OutputPath)" /> |
|||
<EFProjectMetadata Include="Platform: $(Platform)" /> |
|||
<EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" /> |
|||
<EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" /> |
|||
<EFProjectMetadata Include="ProjectDir: $(ProjectDir)" /> |
|||
<EFProjectMetadata Include="RootNamespace: $(RootNamespace)" /> |
|||
<EFProjectMetadata Include="RuntimeFrameworkVersion: $(RuntimeFrameworkVersion)" /> |
|||
<EFProjectMetadata Include="TargetFileName: $(TargetFileName)" /> |
|||
<EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" /> |
|||
<EFProjectMetadata Include="Nullable: $(Nullable)" /> |
|||
<EFProjectMetadata Include="TargetFramework: $(TargetFramework)" /> |
|||
<EFProjectMetadata Include="TargetPlatformIdentifier: $(TargetPlatformIdentifier)" /> |
|||
</ItemGroup> |
|||
<WriteLinesToFile Condition=" '$(TargetFramework)' != '' " |
|||
File="$(EFProjectMetadataFile)" |
|||
Lines="@(EFProjectMetadata)" /> |
|||
</Target> |
|||
</Project> |
@ -0,0 +1,277 @@ |
|||
{ |
|||
"format": 1, |
|||
"restore": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Infrastructure\\CellularManagement.Infrastructure.csproj": {} |
|||
}, |
|||
"projects": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"projectName": "CellularManagement.Application", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
}, |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"projectName": "CellularManagement.Domain", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": {} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.DependencyInjection": { |
|||
"target": "Package", |
|||
"version": "[7.0.0, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
}, |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Infrastructure\\CellularManagement.Infrastructure.csproj": { |
|||
"version": "1.0.0", |
|||
"restore": { |
|||
"projectUniqueName": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Infrastructure\\CellularManagement.Infrastructure.csproj", |
|||
"projectName": "CellularManagement.Infrastructure", |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Infrastructure\\CellularManagement.Infrastructure.csproj", |
|||
"packagesPath": "C:\\Users\\changeself\\.nuget\\packages\\", |
|||
"outputPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Infrastructure\\obj\\", |
|||
"projectStyle": "PackageReference", |
|||
"fallbackFolders": [ |
|||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages" |
|||
], |
|||
"configFilePaths": [ |
|||
"C:\\Users\\changeself\\AppData\\Roaming\\NuGet\\NuGet.Config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config", |
|||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" |
|||
], |
|||
"originalTargetFrameworks": [ |
|||
"net8.0" |
|||
], |
|||
"sources": { |
|||
"D:\\NuGetPackages": {}, |
|||
"https://api.nuget.org/v3/index.json": {}, |
|||
"https://www.nuget.org/api/v2": {} |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"projectReferences": { |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj": { |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Application\\CellularManagement.Application.csproj" |
|||
}, |
|||
"D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj": { |
|||
"projectPath": "D:\\dev\\clean-architecture-starter-main\\CellularManagement\\src\\CellularManagement.Domain\\CellularManagement.Domain.csproj" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"warningProperties": { |
|||
"warnAsError": [ |
|||
"NU1605" |
|||
] |
|||
}, |
|||
"restoreAuditProperties": { |
|||
"enableAudit": "true", |
|||
"auditLevel": "low", |
|||
"auditMode": "direct" |
|||
}, |
|||
"SdkAnalysisLevel": "9.0.100" |
|||
}, |
|||
"frameworks": { |
|||
"net8.0": { |
|||
"targetAlias": "net8.0", |
|||
"dependencies": { |
|||
"Microsoft.AspNetCore.Authentication.JwtBearer": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.AspNetCore.Authorization": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.EntityFrameworkCore.Design": { |
|||
"include": "Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive", |
|||
"suppressParent": "All", |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.Configuration": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Microsoft.Extensions.Configuration.Binder": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Npgsql.EntityFrameworkCore.PostgreSQL": { |
|||
"target": "Package", |
|||
"version": "[8.0.0, )" |
|||
}, |
|||
"Scrutor": { |
|||
"target": "Package", |
|||
"version": "[4.2.2, )" |
|||
} |
|||
}, |
|||
"imports": [ |
|||
"net461", |
|||
"net462", |
|||
"net47", |
|||
"net471", |
|||
"net472", |
|||
"net48", |
|||
"net481" |
|||
], |
|||
"assetTargetFallback": true, |
|||
"warn": true, |
|||
"frameworkReferences": { |
|||
"Microsoft.NETCore.App": { |
|||
"privateAssets": "all" |
|||
} |
|||
}, |
|||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.105/PortableRuntimeIdentifierGraph.json" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess> |
|||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool> |
|||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile> |
|||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot> |
|||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\changeself\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders> |
|||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle> |
|||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.12.2</NuGetToolVersion> |
|||
</PropertyGroup> |
|||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<SourceRoot Include="C:\Users\changeself\.nuget\packages\" /> |
|||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" /> |
|||
</ItemGroup> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\8.0.0\buildTransitive\net8.0\Microsoft.EntityFrameworkCore.props')" /> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.0\build\net8.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\8.0.0\build\net8.0\Microsoft.EntityFrameworkCore.Design.props')" /> |
|||
</ImportGroup> |
|||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">C:\Users\changeself\.nuget\packages\microsoft.codeanalysis.analyzers\3.3.3</PkgMicrosoft_CodeAnalysis_Analyzers> |
|||
</PropertyGroup> |
|||
</Project> |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' "> |
|||
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" /> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" /> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.options\8.0.0\buildTransitive\net6.0\Microsoft.Extensions.Options.targets')" /> |
|||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.0\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" /> |
|||
</ImportGroup> |
|||
</Project> |
@ -0,0 +1,4 @@ |
|||
// <autogenerated />
|
|||
using System; |
|||
using System.Reflection; |
|||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] |
@ -0,0 +1,22 @@ |
|||
//------------------------------------------------------------------------------
|
|||
// <auto-generated>
|
|||
// This code was generated by a tool.
|
|||
//
|
|||
// Changes to this file may cause incorrect behavior and will be lost if
|
|||
// the code is regenerated.
|
|||
// </auto-generated>
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
using System; |
|||
using System.Reflection; |
|||
|
|||
[assembly: System.Reflection.AssemblyCompanyAttribute("CellularManagement.Infrastructure")] |
|||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] |
|||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] |
|||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] |
|||
[assembly: System.Reflection.AssemblyProductAttribute("CellularManagement.Infrastructure")] |
|||
[assembly: System.Reflection.AssemblyTitleAttribute("CellularManagement.Infrastructure")] |
|||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] |
|||
|
|||
// 由 MSBuild WriteCodeFragment 类生成。
|
|||
|
@ -0,0 +1 @@ |
|||
4400330d23beb4f3571ec0e32e6f70021f06398ff98ae8ace59717d132777aff |
@ -0,0 +1,15 @@ |
|||
is_global = true |
|||
build_property.TargetFramework = net8.0 |
|||
build_property.TargetPlatformMinVersion = |
|||
build_property.UsingMicrosoftNETSdkWeb = |
|||
build_property.ProjectTypeGuids = |
|||
build_property.InvariantGlobalization = |
|||
build_property.PlatformNeutralAssembly = |
|||
build_property.EnforceExtendedAnalyzerRules = |
|||
build_property._SupportedPlatformList = Linux,macOS,Windows |
|||
build_property.RootNamespace = CellularManagement.Infrastructure |
|||
build_property.ProjectDir = D:\dev\clean-architecture-starter-main\CellularManagement\src\CellularManagement.Infrastructure\ |
|||
build_property.EnableComHosting = |
|||
build_property.EnableGeneratedComInterfaceComImportInterop = |
|||
build_property.EffectiveAnalysisLevelStyle = 8.0 |
|||
build_property.EnableCodeStyleSeverity = |
@ -0,0 +1,8 @@ |
|||
// <auto-generated/>
|
|||
global using global::System; |
|||
global using global::System.Collections.Generic; |
|||
global using global::System.IO; |
|||
global using global::System.Linq; |
|||
global using global::System.Net.Http; |
|||
global using global::System.Threading; |
|||
global using global::System.Threading.Tasks; |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue