零度框架升级到 Aspire 13.0 版本

This commit is contained in:
hello 2025-12-16 22:26:14 +08:00
parent 41f6c147d5
commit b11ba4f6a5
50 changed files with 336 additions and 446 deletions

View File

@ -4,55 +4,62 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.3.0" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="9.3.0" />
<PackageVersion Include="Aspire.Hosting.RabbitMQ" Version="9.3.0" />
<PackageVersion Include="Aspire.Hosting.Redis" Version="9.3.0" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="9.3.0" />
<PackageVersion Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.3.0" />
<PackageVersion Include="Aspire.RabbitMQ.Client" Version="9.3.0" />
<PackageVersion Include="Aspire.StackExchange.Redis.DistributedCaching" Version="9.3.0" />
<PackageVersion Include="AutoMapper" Version="14.0.0" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Dapr" Version="9.4.0" />
<PackageVersion Include="Aspire.Hosting.Maui" Version="13.0.2-preview.1.25603.5" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="13.0.2" />
<PackageVersion Include="Aspire.Hosting.RabbitMQ" Version="13.0.2" />
<PackageVersion Include="Aspire.Hosting.Redis" Version="13.0.2" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="13.0.2" />
<PackageVersion Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="13.0.2" />
<PackageVersion Include="Aspire.RabbitMQ.Client" Version="13.0.2" />
<PackageVersion Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.0.2" />
<PackageVersion Include="AutoMapper" Version="16.0.0" />
<PackageVersion Include="Blazored.FluentValidation" Version="2.2.0" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Dapr" Version="13.0.1-beta.468" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="Dapr.AspNetCore" Version="1.15.4" />
<PackageVersion Include="EFCore.NamingConventions" Version="9.0.0" />
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageVersion Include="Dapr.AspNetCore" Version="1.16.1" />
<PackageVersion Include="EFCore.NamingConventions" Version="10.0.0-rc.2" />
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.1" />
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
<PackageVersion Include="Grpc.AspNetCore" Version="2.71.0" />
<PackageVersion Include="MediatR" Version="12.5.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.5" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="9.0.5" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.5" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.5" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.50" />
<PackageVersion Include="Microsoft.AspNetCore.Grpc.Swagger" Version="0.9.5" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.5" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.5" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="9.5.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.5.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.3.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery.Yarp" Version="9.3.0" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="9.5.0" />
<PackageVersion Include="Microsoft.Maui.Controls" Version="9.0.50" />
<PackageVersion Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.50" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageVersion Include="MediatR" Version="14.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Authorization" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Grpc.Swagger" Version="0.10.1" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.1" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.1" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="10.1.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.1.0" />
<PackageVersion Include="Microsoft.Extensions.Localization" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Localization.Abstractions" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.1" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.1.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery.Yarp" Version="10.1.0" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.1.0" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components" Version="4.13.2" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.13.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="8.1.2" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0" />
<PackageVersion Include="SharpGrip.FluentValidation.AutoValidation.Mvc" Version="1.5.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.0.1" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,6 @@
{
"solution": {
"path": "HelloShop.sln",
"path": "HelloShop.slnx",
"projects": [
"src\\HelloShop.ApiService\\HelloShop.ApiService.csproj",
"src\\HelloShop.AppHost\\HelloShop.AppHost.csproj",

View File

@ -1,175 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34414.90
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.AppHost", "src\HelloShop.AppHost\HelloShop.AppHost.csproj", "{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ServiceDefaults", "src\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj", "{800A173E-67E6-44BC-9BF1-52562A785A34}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ApiService", "src\HelloShop.ApiService\HelloShop.ApiService.csproj", "{F8D111B0-BF41-4F76-B404-BDDDC53A4462}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.IdentityService", "src\HelloShop.IdentityService\HelloShop.IdentityService.csproj", "{5C355BCB-A344-4259-82D1-1DA07EE9C83A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.OrderingService", "src\HelloShop.OrderingService\HelloShop.OrderingService.csproj", "{C4789097-3694-4370-9252-44268661A26E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ProductService", "src\HelloShop.ProductService\HelloShop.ProductService.csproj", "{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.BasketService", "src\HelloShop.BasketService\HelloShop.BasketService.csproj", "{02EBA5AD-84B4-4AF4-B519-72061C08800D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1AD03316-A743-4E9D-B3BC-FB9499D15141}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{29BE158E-825E-48AB-A02D-4E537A5DC502}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ProductService.UnitTests", "tests\HelloShop.ProductService.UnitTests\HelloShop.ProductService.UnitTests.csproj", "{2022279A-E39F-4489-82AE-39AC53C594C9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.ProductService.FunctionalTests", "tests\HelloShop.ProductService.FunctionalTests\HelloShop.ProductService.FunctionalTests.csproj", "{45932B7F-6ED0-40F3-AA2C-F14A844FEE18}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloShop.FunctionalTests", "tests\HelloShop.FunctionalTests\HelloShop.FunctionalTests.csproj", "{6BAA9747-E0D0-41B9-8A1B-88B777498C43}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.BasketService.UnitTests", "tests\HelloShop.BasketService.UnitTests\HelloShop.BasketService.UnitTests.csproj", "{BE88233A-D6EB-462B-B53C-B588A0BEFAFC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.EventBus.Abstractions", "libraries\HelloShop.EventBus.Abstractions\HelloShop.EventBus.Abstractions.csproj", "{9959387D-8C47-462C-808E-A1E865658C3F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.EventBus.Dapr", "libraries\HelloShop.EventBus.Dapr\HelloShop.EventBus.Dapr.csproj", "{2FD0A058-A447-42C7-A00B-711B2D0B3333}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.EventBus.RabbitMQ", "libraries\HelloShop.EventBus.RabbitMQ\HelloShop.EventBus.RabbitMQ.csproj", "{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.DistributedLock", "libraries\HelloShop.DistributedLock\HelloShop.DistributedLock.csproj", "{86729635-8E31-4C53-81AE-7C410C848219}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.DistributedLock.Dapr", "libraries\HelloShop.DistributedLock.Dapr\HelloShop.DistributedLock.Dapr.csproj", "{37F01A0B-50D6-48BA-8A20-FBADB5524CD7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.EventBus.Logging", "libraries\HelloShop.EventBus.Logging\HelloShop.EventBus.Logging.csproj", "{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.AppShared", "src\HelloShop.AppShared\HelloShop.AppShared.csproj", "{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.WebApp", "src\HelloShop.WebApp\HelloShop.WebApp\HelloShop.WebApp.csproj", "{3D558DAB-E330-0B21-6BFD-6B3CC78AB653}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.WebApp.Client", "src\HelloShop.WebApp\HelloShop.WebApp.Client\HelloShop.WebApp.Client.csproj", "{64268ECF-AB72-5485-9CEA-D8350A202CA8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloShop.HybridApp", "src\HelloShop.HybridApp\HelloShop.HybridApp.csproj", "{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC}.Release|Any CPU.Build.0 = Release|Any CPU
{800A173E-67E6-44BC-9BF1-52562A785A34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{800A173E-67E6-44BC-9BF1-52562A785A34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{800A173E-67E6-44BC-9BF1-52562A785A34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{800A173E-67E6-44BC-9BF1-52562A785A34}.Release|Any CPU.Build.0 = Release|Any CPU
{F8D111B0-BF41-4F76-B404-BDDDC53A4462}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8D111B0-BF41-4F76-B404-BDDDC53A4462}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8D111B0-BF41-4F76-B404-BDDDC53A4462}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8D111B0-BF41-4F76-B404-BDDDC53A4462}.Release|Any CPU.Build.0 = Release|Any CPU
{5C355BCB-A344-4259-82D1-1DA07EE9C83A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C355BCB-A344-4259-82D1-1DA07EE9C83A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C355BCB-A344-4259-82D1-1DA07EE9C83A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C355BCB-A344-4259-82D1-1DA07EE9C83A}.Release|Any CPU.Build.0 = Release|Any CPU
{C4789097-3694-4370-9252-44268661A26E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4789097-3694-4370-9252-44268661A26E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4789097-3694-4370-9252-44268661A26E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4789097-3694-4370-9252-44268661A26E}.Release|Any CPU.Build.0 = Release|Any CPU
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42}.Release|Any CPU.Build.0 = Release|Any CPU
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{02EBA5AD-84B4-4AF4-B519-72061C08800D}.Release|Any CPU.Build.0 = Release|Any CPU
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2022279A-E39F-4489-82AE-39AC53C594C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2022279A-E39F-4489-82AE-39AC53C594C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2022279A-E39F-4489-82AE-39AC53C594C9}.Release|Any CPU.Build.0 = Release|Any CPU
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18}.Release|Any CPU.Build.0 = Release|Any CPU
{6BAA9747-E0D0-41B9-8A1B-88B777498C43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BAA9747-E0D0-41B9-8A1B-88B777498C43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BAA9747-E0D0-41B9-8A1B-88B777498C43}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BAA9747-E0D0-41B9-8A1B-88B777498C43}.Release|Any CPU.Build.0 = Release|Any CPU
{BE88233A-D6EB-462B-B53C-B588A0BEFAFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE88233A-D6EB-462B-B53C-B588A0BEFAFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE88233A-D6EB-462B-B53C-B588A0BEFAFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE88233A-D6EB-462B-B53C-B588A0BEFAFC}.Release|Any CPU.Build.0 = Release|Any CPU
{9959387D-8C47-462C-808E-A1E865658C3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9959387D-8C47-462C-808E-A1E865658C3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9959387D-8C47-462C-808E-A1E865658C3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9959387D-8C47-462C-808E-A1E865658C3F}.Release|Any CPU.Build.0 = Release|Any CPU
{2FD0A058-A447-42C7-A00B-711B2D0B3333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2FD0A058-A447-42C7-A00B-711B2D0B3333}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2FD0A058-A447-42C7-A00B-711B2D0B3333}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2FD0A058-A447-42C7-A00B-711B2D0B3333}.Release|Any CPU.Build.0 = Release|Any CPU
{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD}.Release|Any CPU.Build.0 = Release|Any CPU
{86729635-8E31-4C53-81AE-7C410C848219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{86729635-8E31-4C53-81AE-7C410C848219}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86729635-8E31-4C53-81AE-7C410C848219}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86729635-8E31-4C53-81AE-7C410C848219}.Release|Any CPU.Build.0 = Release|Any CPU
{37F01A0B-50D6-48BA-8A20-FBADB5524CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37F01A0B-50D6-48BA-8A20-FBADB5524CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37F01A0B-50D6-48BA-8A20-FBADB5524CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37F01A0B-50D6-48BA-8A20-FBADB5524CD7}.Release|Any CPU.Build.0 = Release|Any CPU
{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA}.Release|Any CPU.Build.0 = Release|Any CPU
{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A}.Release|Any CPU.Build.0 = Release|Any CPU
{3D558DAB-E330-0B21-6BFD-6B3CC78AB653}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D558DAB-E330-0B21-6BFD-6B3CC78AB653}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D558DAB-E330-0B21-6BFD-6B3CC78AB653}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D558DAB-E330-0B21-6BFD-6B3CC78AB653}.Release|Any CPU.Build.0 = Release|Any CPU
{64268ECF-AB72-5485-9CEA-D8350A202CA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{64268ECF-AB72-5485-9CEA-D8350A202CA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64268ECF-AB72-5485-9CEA-D8350A202CA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64268ECF-AB72-5485-9CEA-D8350A202CA8}.Release|Any CPU.Build.0 = Release|Any CPU
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6E0528E7-81A4-4AA4-9E04-BDDB40CD33EC} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{800A173E-67E6-44BC-9BF1-52562A785A34} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{F8D111B0-BF41-4F76-B404-BDDDC53A4462} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{5C355BCB-A344-4259-82D1-1DA07EE9C83A} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{C4789097-3694-4370-9252-44268661A26E} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{B4C0ADA2-0442-4B7E-BFD9-AA39B52A0D42} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{02EBA5AD-84B4-4AF4-B519-72061C08800D} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{2022279A-E39F-4489-82AE-39AC53C594C9} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
{45932B7F-6ED0-40F3-AA2C-F14A844FEE18} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
{6BAA9747-E0D0-41B9-8A1B-88B777498C43} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
{BE88233A-D6EB-462B-B53C-B588A0BEFAFC} = {29BE158E-825E-48AB-A02D-4E537A5DC502}
{9959387D-8C47-462C-808E-A1E865658C3F} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{2FD0A058-A447-42C7-A00B-711B2D0B3333} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{5D403BF6-9267-4B0F-AEB3-2143C8BBA8CD} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{86729635-8E31-4C53-81AE-7C410C848219} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{37F01A0B-50D6-48BA-8A20-FBADB5524CD7} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{ACBA2FA9-ADBB-4FCD-A303-6D8D4B2131AA} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{6636FED3-3BE6-4A5F-A8F9-15ED4FC71A3A} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{3D558DAB-E330-0B21-6BFD-6B3CC78AB653} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{64268ECF-AB72-5485-9CEA-D8350A202CA8} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
{D2046750-0B6D-41CC-8C87-BE3524FDC9C7} = {1AD03316-A743-4E9D-B3BC-FB9499D15141}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {845545A8-2006-46C3-ABD7-5BDF63F3858C}
EndGlobalSection
EndGlobal

31
HelloShop.slnx Normal file
View File

@ -0,0 +1,31 @@
<Solution>
<Folder Name="/libraries/">
<Project Path="libraries/HelloShop.DistributedLock.Dapr/HelloShop.DistributedLock.Dapr.csproj" />
<Project Path="libraries/HelloShop.DistributedLock/HelloShop.DistributedLock.csproj" />
<Project Path="libraries/HelloShop.EventBus.Abstractions/HelloShop.EventBus.Abstractions.csproj" />
<Project Path="libraries/HelloShop.EventBus.Dapr/HelloShop.EventBus.Dapr.csproj" />
<Project Path="libraries/HelloShop.EventBus.Logging/HelloShop.EventBus.Logging.csproj" />
<Project Path="libraries/HelloShop.EventBus.RabbitMQ/HelloShop.EventBus.RabbitMQ.csproj" />
</Folder>
<Folder Name="/src/">
<Project Path="src/HelloShop.ApiService/HelloShop.ApiService.csproj" />
<Project Path="src/HelloShop.AppHost/HelloShop.AppHost.csproj" />
<Project Path="src/HelloShop.AppShared/HelloShop.AppShared.csproj" />
<Project Path="src/HelloShop.BasketService/HelloShop.BasketService.csproj" />
<Project Path="src/HelloShop.HybridApp/HelloShop.HybridApp.csproj">
<Deploy Solution="Debug|*" />
</Project>
<Project Path="src/HelloShop.IdentityService/HelloShop.IdentityService.csproj" />
<Project Path="src/HelloShop.OrderingService/HelloShop.OrderingService.csproj" />
<Project Path="src/HelloShop.ProductService/HelloShop.ProductService.csproj" />
<Project Path="src/HelloShop.ServiceDefaults/HelloShop.ServiceDefaults.csproj" />
<Project Path="src/HelloShop.WebApp/HelloShop.WebApp.Client/HelloShop.WebApp.Client.csproj" />
<Project Path="src/HelloShop.WebApp/HelloShop.WebApp/HelloShop.WebApp.csproj" />
</Folder>
<Folder Name="/tests/">
<Project Path="tests/HelloShop.BasketService.UnitTests/HelloShop.BasketService.UnitTests.csproj" />
<Project Path="tests/HelloShop.FunctionalTests/HelloShop.FunctionalTests.csproj" />
<Project Path="tests/HelloShop.ProductService.FunctionalTests/HelloShop.ProductService.FunctionalTests.csproj" />
<Project Path="tests/HelloShop.ProductService.UnitTests/HelloShop.ProductService.UnitTests.csproj" />
</Folder>
</Solution>

View File

@ -12,12 +12,12 @@ namespace HelloShop.DistributedLock.Dapr
{
expiryInSeconds = expiryInSeconds == default ? 60 : expiryInSeconds;
// The CallerMemberNameAttribute is used to get the name of the calling method.
string? lockOwner = new StackTrace().GetFrame(1)?.GetMethod()?.DeclaringType?.Name;
lockOwner ??= Guid.NewGuid().ToString();
#pragma warning disable CS0618
#pragma warning disable DAPR_DISTRIBUTEDLOCK // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。
TryLockResponse response = await daprClient.Lock("lockstore", resourceId, lockOwner, expiryInSeconds, cancellationToken);
#pragma warning restore CS0618
#pragma warning restore DAPR_DISTRIBUTEDLOCK // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。
return new DaprDistributedLockResult(response);
}

View File

@ -5,9 +5,9 @@ using Dapr.Client;
namespace HelloShop.DistributedLock.Dapr
{
#pragma warning disable CS0618
#pragma warning disable DAPR_DISTRIBUTEDLOCK // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。
public class DaprDistributedLockResult(TryLockResponse tryLockResponse) : IDistributedLockResult
#pragma warning restore CS0618
#pragma warning restore DAPR_DISTRIBUTEDLOCK // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。
{
public async ValueTask DisposeAsync()
{

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

View File

@ -25,26 +25,26 @@ namespace HelloShop.EventBus.RabbitMQ
private readonly EventBusOptions _eventBusOptions = eventBusOptions.Value;
private IConnection? _rabbitMQConnection;
private IModel? _consumerChannel;
private IChannel? _consumerChannel;
public Task StartAsync(CancellationToken cancellationToken)
{
Task.Factory.StartNew(() =>
Task.Factory.StartNew(async () =>
{
try
{
_rabbitMQConnection = serviceProvider.GetRequiredService<IConnection>();
_consumerChannel = _rabbitMQConnection.CreateModel();
_consumerChannel.ExchangeDeclare(exchange: _exchangeName, type: ExchangeType.Direct);
_consumerChannel.QueueDeclare(queue: _queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
_consumerChannel = await _rabbitMQConnection.CreateChannelAsync();
await _consumerChannel.ExchangeDeclareAsync(exchange: _exchangeName, type: ExchangeType.Direct);
await _consumerChannel.QueueDeclareAsync(queue: _queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
var consumer = new AsyncEventingBasicConsumer(_consumerChannel);
consumer.Received += OnMessageReceivedAsync;
_consumerChannel.BasicConsume(queue: _queueName, autoAck: false, consumer: consumer);
consumer.ReceivedAsync += OnMessageReceivedAsync;
await _consumerChannel.BasicConsumeAsync(queue: _queueName, autoAck: false, consumer: consumer);
foreach (var (eventName, _) in _eventBusOptions.EventTypes)
{
_consumerChannel.QueueBind(queue: _queueName, exchange: _exchangeName, routingKey: eventName);
await _consumerChannel.QueueBindAsync(queue: _queueName, exchange: _exchangeName, routingKey: eventName);
}
}
catch (Exception ex)
@ -58,25 +58,36 @@ namespace HelloShop.EventBus.RabbitMQ
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public void Dispose() => _consumerChannel?.Dispose();
public async void Dispose()
{
if (_consumerChannel is not null)
{
await _consumerChannel.CloseAsync();
await _consumerChannel.DisposeAsync();
}
}
public Task PublishAsync(DistributedEvent @event, CancellationToken cancellationToken = default)
public async Task PublishAsync(DistributedEvent @event, CancellationToken cancellationToken = default)
{
string routingKey = @event.GetType().Name;
using var channel = _rabbitMQConnection?.CreateModel() ?? throw new InvalidOperationException("RabbitMQ connection is not available.");
var channel = _rabbitMQConnection is not null ? await _rabbitMQConnection.CreateChannelAsync(cancellationToken: cancellationToken) : throw new InvalidOperationException("RabbitMQ connection is not available.");
channel.ExchangeDeclare(exchange: _exchangeName, type: ExchangeType.Direct);
var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), _eventBusOptions.JsonSerializerOptions);
return _pipeline.Execute(() =>
await using (channel)
{
IBasicProperties properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2;
channel.BasicPublish(exchange: _exchangeName, routingKey: routingKey, mandatory: true, basicProperties: properties, body: body);
return Task.CompletedTask;
});
await channel.ExchangeDeclareAsync(exchange: _exchangeName, type: ExchangeType.Direct, cancellationToken: cancellationToken);
var body = JsonSerializer.SerializeToUtf8Bytes(@event, @event.GetType(), _eventBusOptions.JsonSerializerOptions);
await _pipeline.ExecuteAsync(async (ct) =>
{
var properties = new BasicProperties
{
DeliveryMode = DeliveryModes.Persistent
};
await channel.BasicPublishAsync(exchange: _exchangeName, routingKey: routingKey, mandatory: true, basicProperties: properties, body: body, cancellationToken: ct);
}, cancellationToken);
}
}
private async Task OnMessageReceivedAsync(object sender, BasicDeliverEventArgs eventArgs)
@ -101,7 +112,10 @@ namespace HelloShop.EventBus.RabbitMQ
}
}
_consumerChannel?.BasicAck(eventArgs.DeliveryTag, multiple: false);
if (_consumerChannel is not null)
{
await _consumerChannel.BasicAckAsync(eventArgs.DeliveryTag, multiple: false);
}
}
private static ResiliencePipeline CreateResiliencePipeline(int retryCount)

View File

@ -17,7 +17,7 @@ namespace HelloShop.EventBus.RabbitMQ
builder.AddRabbitMQClient(connectionName, configureConnectionFactory: factory =>
{
factory.DispatchConsumersAsync = true;
factory.ConsumerDispatchConcurrency = 5;
});
builder.Services.Configure<EventBusOptions>(builder.Configuration.GetSection(sectionName));

View File

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35027.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GarnetWindowsService", "GarnetWindowsService\GarnetWindowsService.csproj", "{AA03C1F8-86B1-446F-B4A0-4A69903351BB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA03C1F8-86B1-446F-B4A0-4A69903351BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA03C1F8-86B1-446F-B4A0-4A69903351BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA03C1F8-86B1-446F-B4A0-4A69903351BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA03C1F8-86B1-446F-B4A0-4A69903351BB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9293CD78-718B-4A38-BE60-4A1C7DF6D3F7}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,3 @@
<Solution>
<Project Path="GarnetWindowsService/GarnetWindowsService.csproj" />
</Solution>

View File

@ -1,43 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34728.123
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTenancySample.SchemaIsolationService", "MultiTenancySample.SchemaIsolationService\MultiTenancySample.SchemaIsolationService.csproj", "{57818F02-DC4F-44CD-89A6-75D00AB5640C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTenancySample.DatabaseIsolationService", "MultiTenancySample.DatabaseIsolationService\MultiTenancySample.DatabaseIsolationService.csproj", "{340A9AE9-C3FA-4555-86AF-395780D2B89B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTenancySample.FieldIsolationService", "MultiTenancySample.FieldIsolationService\MultiTenancySample.FieldIsolationService.csproj", "{0B3EB138-AE17-4EB0-B282-88777F6D5FCA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiTenancySample.ServiceDefaults", "MultiTenancySample.ServiceDefaults\MultiTenancySample.ServiceDefaults.csproj", "{CF4169D1-AB89-42FD-B209-FCBA9B6F0816}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{57818F02-DC4F-44CD-89A6-75D00AB5640C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{57818F02-DC4F-44CD-89A6-75D00AB5640C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{57818F02-DC4F-44CD-89A6-75D00AB5640C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{57818F02-DC4F-44CD-89A6-75D00AB5640C}.Release|Any CPU.Build.0 = Release|Any CPU
{340A9AE9-C3FA-4555-86AF-395780D2B89B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{340A9AE9-C3FA-4555-86AF-395780D2B89B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{340A9AE9-C3FA-4555-86AF-395780D2B89B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{340A9AE9-C3FA-4555-86AF-395780D2B89B}.Release|Any CPU.Build.0 = Release|Any CPU
{0B3EB138-AE17-4EB0-B282-88777F6D5FCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0B3EB138-AE17-4EB0-B282-88777F6D5FCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0B3EB138-AE17-4EB0-B282-88777F6D5FCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0B3EB138-AE17-4EB0-B282-88777F6D5FCA}.Release|Any CPU.Build.0 = Release|Any CPU
{CF4169D1-AB89-42FD-B209-FCBA9B6F0816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF4169D1-AB89-42FD-B209-FCBA9B6F0816}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF4169D1-AB89-42FD-B209-FCBA9B6F0816}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF4169D1-AB89-42FD-B209-FCBA9B6F0816}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {201289BC-2E55-46AF-AD01-B3D4288D9904}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,6 @@
<Solution>
<Project Path="MultiTenancySample.DatabaseIsolationService/MultiTenancySample.DatabaseIsolationService.csproj" />
<Project Path="MultiTenancySample.FieldIsolationService/MultiTenancySample.FieldIsolationService.csproj" />
<Project Path="MultiTenancySample.SchemaIsolationService/MultiTenancySample.SchemaIsolationService.csproj" />
<Project Path="MultiTenancySample.ServiceDefaults/MultiTenancySample.ServiceDefaults.csproj" />
</Solution>

View File

@ -17,7 +17,7 @@ public class OpenApiConfigureOptions(IConfiguredServiceEndPointResolver serviceR
{
foreach (var endPoint in serviceEndpoint.Endpoints ?? [])
{
UriBuilder uriBuilder = new(endPoint) { Path = "swagger/v1/swagger.json" };
UriBuilder uriBuilder = new(endPoint) { Path = "/openapi/v1.json" };
try
{
@ -35,12 +35,15 @@ public class OpenApiConfigureOptions(IConfiguredServiceEndPointResolver serviceR
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get swagger endpoint for {ServiceName}", serviceEndpoint.ServiceName);
if (logger.IsEnabled(LogLevel.Error))
{
logger.LogError(ex, "Failed to get swagger endpoint for {ServiceName}", serviceEndpoint.ServiceName);
}
}
}
}
options.ConfigObject.Urls = urlDescriptors;
options.SwaggerEndpoint("v1/swagger.json", "apiservice");
options.SwaggerEndpoint("/openapi/v1.json", "apiservice");
}
}

View File

@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" />

View File

@ -46,6 +46,6 @@ app.MapReverseProxy();
app.MapControllers();
app.UseOpenApi();
app.UseOpenApiWithUI();
app.Run();

View File

@ -1,8 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.3.0" />
<Project Sdk="Aspire.AppHost.Sdk/13.0.2">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
@ -15,7 +14,7 @@
<ProjectReference Include="..\HelloShop.WebApp\HelloShop.WebApp\HelloShop.WebApp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
<PackageReference Include="Aspire.Hosting.Maui" />
<PackageReference Include="Aspire.Hosting.PostgreSQL" />
<PackageReference Include="Aspire.Hosting.RabbitMQ" />
<PackageReference Include="Aspire.Hosting.Redis" />

View File

@ -3,6 +3,7 @@
using CommunityToolkit.Aspire.Hosting.Dapr;
using HelloShop.AppHost.Extensions;
using k8s.Models;
var builder = DistributedApplication.CreateBuilder(args);
@ -50,7 +51,7 @@ var basketService = builder.AddProject<Projects.HelloShop_BasketService>("basket
options.WithOptions(daprSidecarOptions).WithReferenceAndWaitFor(rabbitmq).WithReferenceAndWaitFor(cache);
});
var apiservice = builder.AddProject<Projects.HelloShop_ApiService>("apiservice")
var apiService = builder.AddProject<Projects.HelloShop_ApiService>("apiservice")
.WithReference(identityService).WaitFor(identityService)
.WithReference(orderingService).WaitFor(orderingService)
.WithReference(productService).WaitFor(productService)
@ -58,7 +59,14 @@ var apiservice = builder.AddProject<Projects.HelloShop_ApiService>("apiservice")
.WithDaprSidecar();
builder.AddProject<Projects.HelloShop_WebApp>("webapp")
.WithReference(apiservice).WaitFor(apiservice)
.WithReference(apiService).WaitFor(apiService)
.WithDaprSidecar();
var mauiapp = builder.AddMauiProject("hybridapp", "../HelloShop.HybridApp/HelloShop.HybridApp.csproj");
mauiapp.AddWindowsDevice().WithReference(apiService).WaitFor(apiService);
mauiapp.AddMacCatalystDevice().WithReference(apiService).WaitFor(apiService);
mauiapp.AddiOSSimulator().WithReference(apiService).WaitFor(apiService);
mauiapp.AddAndroidEmulator().WithReference(apiService).WaitFor(apiService);
builder.Build().Run();

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

View File

@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IncludeHttpRuleProtos>true</IncludeHttpRuleProtos>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>
<ItemGroup>
<None Remove="Protos\basket.proto" />

View File

@ -8,7 +8,10 @@ using HelloShop.BasketService.Services;
using HelloShop.EventBus.Abstractions;
using HelloShop.EventBus.Dapr;
using HelloShop.ServiceDefaults.Extensions;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.Reflection;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
@ -33,7 +36,7 @@ builder.Services.AddSingleton<IBasketRepository, BasketRepository>();
builder.Services.AddGrpc().AddJsonTranscoding();
builder.Services.AddGrpcSwagger();
builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();
builder.Services.AddCustomLocalization();
builder.Services.AddModelMapper().AddModelValidator();
@ -60,7 +63,15 @@ app.UseAuthentication().UseAuthorization();
app.MapGrpcService<GreeterService>();
app.MapGrpcService<CustomerBasketService>();
app.UseCustomLocalization();
app.UseOpenApi();
app.UseSwagger(c =>
{
c.RouteTemplate = "openapi/{documentName}.json";
});
app.UseSwaggerUI(c =>
{
c.InjectStylesheet("/ServiceDefaults/Resources/OpenApi/Custom.css");
c.SwaggerEndpoint("/openapi/v1.json", "v1");
});
app.MapGroup("api/Permissions").MapPermissionDefinitions("Permissions");
// End configure extensions request pipeline.
app.Run();

View File

@ -7,7 +7,7 @@
},
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
"Protocols": "Http1AndHttp2AndHttp3"
}
},
"AllowedHosts": "*"

View File

@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
<TargetFrameworks>net10.0-android;net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
<!-- <TargetFrameworks>$(TargetFrameworks);net10.0-tizen</TargetFrameworks> -->
<!-- Note for MacCatalyst:
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
@ -38,8 +38,8 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">24.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup>
@ -62,9 +62,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.70" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.70" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.5" />
<PackageReference Include="Microsoft.Maui.Controls" Version="10.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" />

View File

@ -61,7 +61,7 @@ builder.Services.AddAuthentication(options =>
options.SecurityAlgorithm = SecurityAlgorithms.HmacSha256;
});
builder.Services.AddOpenApi();
builder.Services.AddOpenApiServices();
builder.Services.AddPermissionDefinitions();
builder.Services.AddAuthorization().AddDistributedMemoryCache().AddHttpClient().AddHttpContextAccessor().AddTransient<IPermissionChecker, LocalPermissionChecker>().AddCustomAuthorization();
builder.Services.AddModelMapper().AddModelValidator();
@ -78,7 +78,7 @@ app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(
app.MapControllers();
app.UseOpenApi();
app.UseOpenApiWithUI();
app.MapGroup("api/Permissions").MapPermissionDefinitions("Permissions");
app.UseCustomLocalization();

View File

@ -70,7 +70,7 @@ namespace HelloShop.OrderingService.Extensions
builder.Services.AddDistributedEventLogs<OrderingServiceDbContext>().AddTransient<IDistributedEventService, DistributedEventService>();
builder.Services.AddOpenApi();
builder.Services.AddOpenApiServices();
builder.Services.AddSingleton(TimeProvider.System);
}
@ -78,7 +78,7 @@ namespace HelloShop.OrderingService.Extensions
public static WebApplication MapApplicationEndpoints(this WebApplication app)
{
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseOpenApi();
app.UseOpenApiWithUI();
app.MapDaprEventBus();
return app;

View File

@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\libraries\HelloShop.EventBus.Dapr\HelloShop.EventBus.Dapr.csproj" />

View File

@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InterceptorsNamespaces>$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated</InterceptorsNamespaces>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\libraries\HelloShop.DistributedLock.Dapr\HelloShop.DistributedLock.Dapr.csproj" />

View File

@ -41,7 +41,7 @@ builder.AddNpgsqlDbContext<ProductServiceDbContext>(connectionName: DbConstants.
builder.Services.AddSingleton<MigrationService<ProductServiceDbContext>>().AddHostedService<DataSeeder>();
builder.Services.AddHttpClient().AddHttpContextAccessor().AddDistributedMemoryCache();
builder.Services.AddCustomLocalization();
builder.Services.AddOpenApi();
builder.Services.AddOpenApiServices();
builder.Services.AddModelMapper().AddModelValidator();
builder.Services.AddLocalization().AddPermissionDefinitions();
builder.Services.AddAuthorization().AddRemotePermissionChecker().AddCustomAuthorization();
@ -63,7 +63,7 @@ app.MapControllers();
// Configure extensions request pipeline.
app.UseCustomLocalization();
app.UseOpenApi();
app.UseOpenApiWithUI();
app.MapGroup("api/Permissions").MapPermissionDefinitions("Permissions");
app.MapDaprEventBus();
// End configure extensions request pipeline.
@ -71,8 +71,3 @@ app.MapDaprEventBus();
await app.Services.GetRequiredService<MigrationService<ProductServiceDbContext>>().ExecuteAsync();
await app.RunAsync();
/// <summary>
/// The test project requires a public Program type.
/// </summary>
public partial class Program { }

View File

@ -2,9 +2,9 @@
// See the license file in the project root for more information.
using FluentValidation;
using FluentValidation.AspNetCore;
using HelloShop.ServiceDefaults.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using SharpGrip.FluentValidation.AutoValidation.Mvc.Extensions;
using System.Reflection;
namespace HelloShop.ServiceDefaults.Extensions;
@ -15,7 +15,10 @@ public static class ModelBindingExtensionns
{
assembly ??= Assembly.GetCallingAssembly();
services.AddAutoMapper(assembly);
services.AddAutoMapper(cfg =>
{
cfg.AddMaps(assembly);
});
return services;
}

View File

@ -3,9 +3,10 @@
using HelloShop.ServiceDefaults.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
@ -15,54 +16,75 @@ namespace HelloShop.ServiceDefaults.Extensions
{
public static class OpenApiExtensions
{
public static IServiceCollection AddOpenApi(this IServiceCollection services, Action<SwaggerGenOptions>? configureOptions = null)
public static IServiceCollection AddOpenApiServices(this IServiceCollection services, Action<OpenApiOptions>? configureOptions = null)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(configureOptions);
services.Configure<SwaggerUIOptions>(options =>
services.AddOpenApi(options =>
{
options.DocumentTitle = Assembly.GetEntryAssembly()?.GetName().Name;
options.InjectStylesheet("/ServiceDefaults/Resources/OpenApi/Custom.css");
});
services.Configure<SwaggerGenOptions>(options =>
{
options.OperationFilter<AcceptLanguageHeaderOperationFilter>();
options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Description = "JWT Authorization header using the Bearer scheme."
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }
},
Array.Empty<string>()
}
});
options.AddDocumentTransformer<BearerSecuritySchemeTransformer>();
options.AddDocumentTransformer<AcceptLanguageHeaderDocumentTransformer>();
configureOptions?.Invoke(options);
});
return services;
}
public static IApplicationBuilder UseOpenApi(this IApplicationBuilder app, Action<SwaggerOptions>? apiConfigureOptions = null, Action<SwaggerUIOptions>? uiConfigureOptions = null)
internal sealed class BearerSecuritySchemeTransformer : IOpenApiDocumentTransformer
{
app.UseSwagger(apiConfigureOptions);
app.UseSwaggerUI(uiConfigureOptions);
public Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
{
var securityScheme = new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT",
Description = "JWT Authorization header using the Bearer scheme."
};
document.Components ??= new OpenApiComponents();
document.Components.SecuritySchemes = new Dictionary<string, IOpenApiSecurityScheme>
{
["bearerAuth"] = securityScheme
};
var securitySchemeReference = new OpenApiSecuritySchemeReference("bearerAuth", document);
var securityRequirement = new OpenApiSecurityRequirement
{
[securitySchemeReference] = []
};
foreach (var path in document.Paths.Values)
{
if (path.Operations != null)
{
foreach (var operation in path.Operations.Values)
{
operation.Security ??= [];
operation.Security.Add(securityRequirement);
}
}
}
return Task.CompletedTask;
}
}
public static WebApplication UseOpenApiWithUI(this WebApplication app, Action<SwaggerUIOptions>? uiConfigureOptions = null)
{
app.MapOpenApi();
app.Map("/ServiceDefaults", appBuilder => appBuilder.UseStaticFiles(new StaticFileOptions
{
FileProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly())
}));
app.UseSwaggerUI(options => {
options.DocumentTitle = Assembly.GetEntryAssembly()?.GetName().Name;
options.InjectStylesheet("/ServiceDefaults/Resources/OpenApi/Custom.css");
options.SwaggerEndpoint("/openapi/v1.json", "v1");
uiConfigureOptions?.Invoke(options);
});
return app;
}
}

View File

@ -1,13 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>
<ItemGroup>
<None Remove="Resources\OpenApi\logo-white.svg" />
</ItemGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Dapr.AspNetCore" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
@ -15,11 +20,12 @@
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
<PackageReference Include="SharpGrip.FluentValidation.AutoValidation.Mvc" />
<PackageReference Include="Swashbuckle.AspNetCore" />
<PackageReference Include="AutoMapper" />
<PackageReference Include="FluentValidation.AspNetCore" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\OpenApi\Custom.css" />
<EmbeddedResource Include="Resources\OpenApi\logo-white.svg" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,43 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Net.Http.Headers;
using Microsoft.OpenApi;
namespace HelloShop.ServiceDefaults.Infrastructure
{
public sealed class AcceptLanguageHeaderDocumentTransformer : IOpenApiDocumentTransformer
{
public Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
{
var parameter = new OpenApiParameter
{
Name = HeaderNames.AcceptLanguage,
In = ParameterLocation.Header,
Required = false,
Schema = new OpenApiSchema
{
Type = JsonSchemaType.String,
Default = "zh-CN",
Enum = ["zh-CN", "en-US"]
}
};
foreach (var path in document.Paths.Values)
{
if (path.Operations != null)
{
foreach (var operation in path.Operations.Values)
{
operation.Parameters ??= [];
operation.Parameters.Add(parameter);
}
continue;
}
}
return Task.CompletedTask;
}
}
}

View File

@ -1,30 +0,0 @@
// Copyright (c) HelloShop Corporation. All rights reserved.
// See the license file in the project root for more information.
using Microsoft.Net.Http.Headers;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace HelloShop.ServiceDefaults.Infrastructure;
public class AcceptLanguageHeaderOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var parameter = new OpenApiParameter
{
Name = HeaderNames.AcceptLanguage,
In = ParameterLocation.Header,
Required = false,
Schema = new OpenApiSchema
{
Default = new OpenApiString("zh-CN"),
Type = "string",
Enum = [new OpenApiString("zh-CN"), new OpenApiString("en-US")]
}
};
operation.Parameters.Add(parameter);
}
}

View File

@ -3,7 +3,7 @@
}
.swagger-ui .topbar-wrapper a.link::before {
content: url('https://cloud.helloworldnet.com/logo-white.svg');
content: url('/ServiceDefaults/Resources/OpenApi/logo-white.svg');
height: 40px;
width: 40px;
}

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<polygon class="g-fill-primary" fill="white" points="56.14870071411133,9.169990539550781 42.863704681396484,3.4079971313476562 42.863704681396484,49.37999725341797 3.851299285888672,43.495994567871094 42.60969924926758,56.592002868652344 56.14870071411133,51.05199432373047 "/>
<circle class="g-fill-primary" cx="37.52137" cy="10.68376" r="3" stroke="white" stroke-width="2" fill="transparent" />
<rect class="g-fill-primary" x="13.33333" y="14.2906" width="18.20513" height="25.98291" stroke="white" stroke-width="3" fill="transparent" />
</svg>

After

Width:  |  Height:  |  Size: 613 B

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>

View File

@ -57,7 +57,7 @@ namespace HelloShop.BasketService.UnitTests.Services
var logger = NullLogger<CustomerBasketService>.Instance;
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>(), new NullLoggerFactory()));
var service = new CustomerBasketService(basketRepositoryMock.Object, logger, mapper, validatorMock.Object);
@ -85,7 +85,7 @@ namespace HelloShop.BasketService.UnitTests.Services
basketRepositoryMock.Setup(x => x.UpdateBasketAsync(It.IsAny<CustomerBasket>(), It.IsAny<CancellationToken>())).ReturnsAsync((CustomerBasket basket, CancellationToken token) => basket);
var logger = NullLogger<CustomerBasketService>.Instance;
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>(), new NullLoggerFactory()));
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();
validatorMock.Setup(x => x.ValidateAsync(It.IsAny<UpdateBasketRequest>(), It.IsAny<CancellationToken>())).ReturnsAsync(new ValidationResult());
@ -119,7 +119,7 @@ namespace HelloShop.BasketService.UnitTests.Services
// Arrange
var basketRepositoryMock = new Mock<IBasketRepository>();
var logger = NullLogger<CustomerBasketService>.Instance;
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>()));
var mapper = new Mapper(new MapperConfiguration(cfg => cfg.AddProfile<BasketsMapConfiguration>(), new NullLoggerFactory()));
var validatorMock = new Mock<IValidator<UpdateBasketRequest>>();

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>

View File

@ -7,6 +7,7 @@ using HelloShop.ProductService.Entities.Products;
using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
namespace HelloShop.ProductService.UnitTests
@ -22,7 +23,7 @@ namespace HelloShop.ProductService.UnitTests
mock.Setup(m => m.FindAsync(It.Is<int>(id => id == 1), It.IsAny<CancellationToken>())).ReturnsAsync((Product?)null);
// Act
IMapper mapper = new Mapper(new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductDetailsResponse>()));
IMapper mapper = new Mapper(new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductDetailsResponse>(), new NullLoggerFactory()));
MockProductsController mockProductsController = new(mock.Object, mapper);
ActionResult<ProductDetailsResponse> result = await mockProductsController.GetProduct(1);
@ -44,7 +45,7 @@ namespace HelloShop.ProductService.UnitTests
mock.Setup(m => m.GetAllAsync(It.IsAny<CancellationToken>())).ReturnsAsync(mockProducts);
// Act
IMapper mapper = new Mapper(new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductListItem>()));
IMapper mapper = new Mapper(new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductListItem>(), new NullLoggerFactory()));
MockProductsController mockProductsController = new(mock.Object, mapper);
ActionResult<IEnumerable<ProductListItem>> result = await mockProductsController.GetProducts();

View File

@ -9,6 +9,7 @@ using HelloShop.ProductService.Infrastructure;
using HelloShop.ProductService.Models.Products;
using HelloShop.ProductService.UnitTests.Helpers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Time.Testing;
namespace HelloShop.ProductService.UnitTests
@ -25,7 +26,7 @@ namespace HelloShop.ProductService.UnitTests
await dbContext.SaveChangesAsync();
IMapper mapper = new MapperConfiguration(configure => configure.CreateMap<Product, ProductDetailsResponse>()).CreateMapper();
IMapper mapper = new Mapper(new MapperConfiguration(cfg => cfg.CreateMap<Product, ProductListItem>(), new NullLoggerFactory()));
ProductsController productsController = new(dbContext, mapper);
@ -45,7 +46,7 @@ namespace HelloShop.ProductService.UnitTests
// Arrange
await using ProductServiceDbContext dbContext = new FakeDbContextFactory().CreateDbContext();
IMapper mapper = new MapperConfiguration(configure => configure.AddProfile<ProductsMapConfiguration>()).CreateMapper();
IMapper mapper = new MapperConfiguration(configure => configure.AddProfile<ProductsMapConfiguration>(),new NullLoggerFactory()).CreateMapper();
ProductsController productsController = new(dbContext, mapper);