diff --git a/Vertical.Slice.Template.sln b/Vertical.Slice.Template.sln
index 94b27b1..a2a8dbc 100644
--- a/Vertical.Slice.Template.sln
+++ b/Vertical.Slice.Template.sln
@@ -27,10 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.Con
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.TestsShared", "tests\Vertical.Slice.Template.TestsShared\Vertical.Slice.Template.TestsShared.csproj", "{E3C9B67C-8443-49C9-A6F3-EA099199F66F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.Shared", "src\Vertical.Slice.Template.Shared\Vertical.Slice.Template.Shared.csproj", "{05B80842-E143-46CA-A881-CF14A85D927C}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.ApiClient", "src\Vertical.Slice.Template.ApiClient\Vertical.Slice.Template.ApiClient.csproj", "{51C30F5B-FC3F-41C2-BD7C-FA254B956C55}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution-items", "solution-items", "{798579C1-7DEC-47A2-9C18-CA3DBE4A6573}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -72,10 +68,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\publish.yml = .github\workflows\publish.yml
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template", "src\Vertical.Slice.Template\Vertical.Slice.Template.csproj", "{31F7A4C7-66DD-4387-9981-4A64501018E7}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.Api", "src\Vertical.Slice.Template.Api\Vertical.Slice.Template.Api.csproj", "{F45584B2-2831-410B-BC9D-3E13817E768F}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".devcontainer", ".devcontainer", "{268E2B03-D9F4-4D31-84BA-6D1DC250E894}"
ProjectSection(SolutionItems) = preProject
.devcontainer\devcontainer.json = .devcontainer\devcontainer.json
@@ -98,6 +90,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker-compose", "docker-co
deployments\docker-compose\docker-compose.infrastructure.yaml = deployments\docker-compose\docker-compose.infrastructure.yaml
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiClients", "ApiClients", "{66D6E224-01FF-4D8F-98C1-CEA3CD2D5F15}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "App", "App", "{AF80152C-AF0D-475E-AD69-A7867D1ACA26}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{54C91A04-E128-4ADB-9B49-E0FEAC783069}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiClients", "src\ApiClients\ApiClients.csproj", "{56A79202-F0BB-4BDB-B042-B773EDBCDFE3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template", "src\App\Vertical.Slice.Template\Vertical.Slice.Template.csproj", "{AC478225-5EA9-4895-875A-0B01217C4576}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vertical.Slice.Template.Api", "src\App\Vertical.Slice.Template.Api\Vertical.Slice.Template.Api.csproj", "{23F3C3DD-6630-4743-BE50-9BD6F719665E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "src\Shared\Shared.csproj", "{A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -119,14 +125,17 @@ Global
{A79D441C-D450-474E-9CFC-008335A80B13} = {C4B80800-5430-4D4E-B473-261157D54CD4}
{AEFEEF63-5831-49E5-A7D9-892AF653C32D} = {798579C1-7DEC-47A2-9C18-CA3DBE4A6573}
{ED6C6F59-8A39-4D7D-BB93-888AA486AFE9} = {AEFEEF63-5831-49E5-A7D9-892AF653C32D}
- {51C30F5B-FC3F-41C2-BD7C-FA254B956C55} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
- {05B80842-E143-46CA-A881-CF14A85D927C} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
- {31F7A4C7-66DD-4387-9981-4A64501018E7} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
- {F45584B2-2831-410B-BC9D-3E13817E768F} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
{268E2B03-D9F4-4D31-84BA-6D1DC250E894} = {798579C1-7DEC-47A2-9C18-CA3DBE4A6573}
{3A68A53A-1E76-49DE-A622-569267333288} = {268E2B03-D9F4-4D31-84BA-6D1DC250E894}
{9DF99E09-AEC5-4F44-BC7E-CB16EF796431} = {798579C1-7DEC-47A2-9C18-CA3DBE4A6573}
{F3FCF437-0EF6-4149-AA20-46C787B6FCB1} = {9DF99E09-AEC5-4F44-BC7E-CB16EF796431}
+ {66D6E224-01FF-4D8F-98C1-CEA3CD2D5F15} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
+ {AF80152C-AF0D-475E-AD69-A7867D1ACA26} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
+ {54C91A04-E128-4ADB-9B49-E0FEAC783069} = {9BB0311A-FE23-4C8D-B7C0-E8CD49FA3D20}
+ {56A79202-F0BB-4BDB-B042-B773EDBCDFE3} = {66D6E224-01FF-4D8F-98C1-CEA3CD2D5F15}
+ {AC478225-5EA9-4895-875A-0B01217C4576} = {AF80152C-AF0D-475E-AD69-A7867D1ACA26}
+ {23F3C3DD-6630-4743-BE50-9BD6F719665E} = {AF80152C-AF0D-475E-AD69-A7867D1ACA26}
+ {A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4} = {54C91A04-E128-4ADB-9B49-E0FEAC783069}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5F41BF51-E13B-48BF-8D81-874FBA9BC961}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -149,14 +158,6 @@ Global
{E3C9B67C-8443-49C9-A6F3-EA099199F66F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3C9B67C-8443-49C9-A6F3-EA099199F66F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3C9B67C-8443-49C9-A6F3-EA099199F66F}.Release|Any CPU.Build.0 = Release|Any CPU
- {05B80842-E143-46CA-A881-CF14A85D927C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {05B80842-E143-46CA-A881-CF14A85D927C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {05B80842-E143-46CA-A881-CF14A85D927C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {05B80842-E143-46CA-A881-CF14A85D927C}.Release|Any CPU.Build.0 = Release|Any CPU
- {51C30F5B-FC3F-41C2-BD7C-FA254B956C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {51C30F5B-FC3F-41C2-BD7C-FA254B956C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {51C30F5B-FC3F-41C2-BD7C-FA254B956C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {51C30F5B-FC3F-41C2-BD7C-FA254B956C55}.Release|Any CPU.Build.0 = Release|Any CPU
{4E185D04-8B8D-4BE9-AAE3-5406C703DF83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E185D04-8B8D-4BE9-AAE3-5406C703DF83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E185D04-8B8D-4BE9-AAE3-5406C703DF83}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -165,13 +166,21 @@ Global
{A79D441C-D450-474E-9CFC-008335A80B13}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A79D441C-D450-474E-9CFC-008335A80B13}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A79D441C-D450-474E-9CFC-008335A80B13}.Release|Any CPU.Build.0 = Release|Any CPU
- {31F7A4C7-66DD-4387-9981-4A64501018E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {31F7A4C7-66DD-4387-9981-4A64501018E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {31F7A4C7-66DD-4387-9981-4A64501018E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {31F7A4C7-66DD-4387-9981-4A64501018E7}.Release|Any CPU.Build.0 = Release|Any CPU
- {F45584B2-2831-410B-BC9D-3E13817E768F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F45584B2-2831-410B-BC9D-3E13817E768F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F45584B2-2831-410B-BC9D-3E13817E768F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F45584B2-2831-410B-BC9D-3E13817E768F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {56A79202-F0BB-4BDB-B042-B773EDBCDFE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {56A79202-F0BB-4BDB-B042-B773EDBCDFE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {56A79202-F0BB-4BDB-B042-B773EDBCDFE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {56A79202-F0BB-4BDB-B042-B773EDBCDFE3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AC478225-5EA9-4895-875A-0B01217C4576}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AC478225-5EA9-4895-875A-0B01217C4576}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AC478225-5EA9-4895-875A-0B01217C4576}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AC478225-5EA9-4895-875A-0B01217C4576}.Release|Any CPU.Build.0 = Release|Any CPU
+ {23F3C3DD-6630-4743-BE50-9BD6F719665E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {23F3C3DD-6630-4743-BE50-9BD6F719665E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {23F3C3DD-6630-4743-BE50-9BD6F719665E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {23F3C3DD-6630-4743-BE50-9BD6F719665E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A5FB3B9E-FF0A-45F4-8D37-080C770A5AB4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/src/Vertical.Slice.Template.ApiClient/Vertical.Slice.Template.ApiClient.csproj b/src/ApiClients/ApiClients.csproj
similarity index 100%
rename from src/Vertical.Slice.Template.ApiClient/Vertical.Slice.Template.ApiClient.csproj
rename to src/ApiClients/ApiClients.csproj
diff --git a/src/Vertical.Slice.Template.ApiClient/Clients/CatalogsClient.g.cs b/src/ApiClients/Clients/CatalogsClient.g.cs
similarity index 100%
rename from src/Vertical.Slice.Template.ApiClient/Clients/CatalogsClient.g.cs
rename to src/ApiClients/Clients/CatalogsClient.g.cs
diff --git a/src/Vertical.Slice.Template.ApiClient/nswag.json b/src/ApiClients/nswag.json
similarity index 100%
rename from src/Vertical.Slice.Template.ApiClient/nswag.json
rename to src/ApiClients/nswag.json
diff --git a/src/Vertical.Slice.Template.ApiClient/swagger.json b/src/ApiClients/swagger.json
similarity index 100%
rename from src/Vertical.Slice.Template.ApiClient/swagger.json
rename to src/ApiClients/swagger.json
diff --git a/src/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs b/src/App/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs
similarity index 51%
rename from src/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs
rename to src/App/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs
index 7b7563f..9cf3a13 100644
--- a/src/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs
+++ b/src/App/Vertical.Slice.Template.Api/CatalogsApiMetadata.cs
@@ -1,3 +1,3 @@
namespace Vertical.Slice.Template.Api;
-public class CatalogsApiMetadata { }
+public class CatalogsApiMetadata;
diff --git a/src/Vertical.Slice.Template.Api/Program.cs b/src/App/Vertical.Slice.Template.Api/Program.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Api/Program.cs
rename to src/App/Vertical.Slice.Template.Api/Program.cs
index a8a5dd9..2fb6237 100644
--- a/src/Vertical.Slice.Template.Api/Program.cs
+++ b/src/App/Vertical.Slice.Template.Api/Program.cs
@@ -1,13 +1,13 @@
using System.Reflection;
using Serilog;
using Serilog.Events;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.Logging;
+using Shared.Swagger;
+using Shared.Web.Minimal.Extensions;
using Vertical.Slice.Template;
using Vertical.Slice.Template.Shared;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
using Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
-using Vertical.Slice.Template.Shared.Logging;
-using Vertical.Slice.Template.Shared.Swagger;
-using Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
// https://github.com/serilog/serilog-aspnetcore#two-stage-initialization
Log.Logger = new LoggerConfiguration()
diff --git a/src/Vertical.Slice.Template.Api/Properties/launchSettings.json b/src/App/Vertical.Slice.Template.Api/Properties/launchSettings.json
similarity index 100%
rename from src/Vertical.Slice.Template.Api/Properties/launchSettings.json
rename to src/App/Vertical.Slice.Template.Api/Properties/launchSettings.json
diff --git a/src/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj b/src/App/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj
similarity index 61%
rename from src/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj
rename to src/App/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj
index f7163bf..94145bf 100644
--- a/src/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj
+++ b/src/App/Vertical.Slice.Template.Api/Vertical.Slice.Template.Api.csproj
@@ -4,4 +4,8 @@
+
+
+
+
diff --git a/src/Vertical.Slice.Template.Api/appsettings.Development.json b/src/App/Vertical.Slice.Template.Api/appsettings.Development.json
similarity index 100%
rename from src/Vertical.Slice.Template.Api/appsettings.Development.json
rename to src/App/Vertical.Slice.Template.Api/appsettings.Development.json
diff --git a/src/Vertical.Slice.Template.Api/appsettings.json b/src/App/Vertical.Slice.Template.Api/appsettings.json
similarity index 100%
rename from src/Vertical.Slice.Template.Api/appsettings.json
rename to src/App/Vertical.Slice.Template.Api/appsettings.json
diff --git a/src/Vertical.Slice.Template.Api/appsettings.test.json b/src/App/Vertical.Slice.Template.Api/appsettings.test.json
similarity index 100%
rename from src/Vertical.Slice.Template.Api/appsettings.test.json
rename to src/App/Vertical.Slice.Template.Api/appsettings.test.json
diff --git a/src/Vertical.Slice.Template/CatalogsMetadata.cs b/src/App/Vertical.Slice.Template/CatalogsMetadata.cs
similarity index 100%
rename from src/Vertical.Slice.Template/CatalogsMetadata.cs
rename to src/App/Vertical.Slice.Template/CatalogsMetadata.cs
diff --git a/src/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs b/src/App/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs
similarity index 95%
rename from src/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs
rename to src/App/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs
index 3c77a33..48f3ba1 100644
--- a/src/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs
+++ b/src/App/Vertical.Slice.Template/Products/Data/Configurations/ProductEntityTypeConfigurations.cs
@@ -1,9 +1,9 @@
using Humanizer;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Shared.EF;
using Vertical.Slice.Template.Products.Models;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.EF;
namespace Vertical.Slice.Template.Products.Data.Configurations;
diff --git a/src/Vertical.Slice.Template/Products/Data/Configurations/SieveProductReadConfigurations.cs b/src/App/Vertical.Slice.Template/Products/Data/Configurations/SieveProductReadConfigurations.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/Data/Configurations/SieveProductReadConfigurations.cs
rename to src/App/Vertical.Slice.Template/Products/Data/Configurations/SieveProductReadConfigurations.cs
diff --git a/src/Vertical.Slice.Template/Products/Dtos/v1/ProductDto.cs b/src/App/Vertical.Slice.Template/Products/Dtos/v1/ProductDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/Dtos/v1/ProductDto.cs
rename to src/App/Vertical.Slice.Template/Products/Dtos/v1/ProductDto.cs
diff --git a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs
similarity index 63%
rename from src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs
rename to src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs
index 1f6463e..96753af 100644
--- a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProduct.cs
@@ -2,14 +2,14 @@
using FluentValidation;
using MediatR;
using Microsoft.Extensions.Logging;
+using Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Extensions;
+using Shared.Core.Id;
+using Shared.EF.Extensions;
+using Shared.Validation.Extensions;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Core.Id;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.EF.Extensions;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
namespace Vertical.Slice.Template.Products.Features.CreatingProduct.v1;
@@ -20,7 +20,7 @@ namespace Vertical.Slice.Template.Products.Features.CreatingProduct.v1;
// https://codeopinion.com/leaking-value-objects-from-your-domain/
// https://www.youtube.com/watch?v=CdanF8PWJng
// we don't pass value-objects and domains to our commands and events, just primitive types
-public record CreateProduct(string Name, Guid CategoryId, decimal Price, string? Description = null)
+internal record CreateProduct(string Name, Guid CategoryId, decimal Price, string? Description = null)
: ICommand
{
public Guid Id { get; } = IdGenerator.NewId();
@@ -50,38 +50,25 @@ public CreateProductValidator()
}
}
-internal class CreateProductHandler : ICommandHandler
+internal class CreateProductHandler(
+ DbExecuters.CreateAndSaveProductExecutor createAndSaveProductExecutor,
+ IMapper mapper,
+ IMediator mediator,
+ ILogger logger
+) : ICommandHandler
{
- private readonly DbExecuters.CreateAndSaveProductExecutor _createAndSaveProductExecutor;
- private readonly IMapper _mapper;
- private readonly IMediator _mediator;
- private readonly ILogger _logger;
-
- public CreateProductHandler(
- DbExecuters.CreateAndSaveProductExecutor createAndSaveProductExecutor,
- IMapper mapper,
- IMediator mediator,
- ILogger logger
- )
- {
- _createAndSaveProductExecutor = createAndSaveProductExecutor;
- _mapper = mapper;
- _mediator = mediator;
- _logger = logger;
- }
-
public async Task Handle(CreateProduct request, CancellationToken cancellationToken)
{
request.NotBeNull();
- var product = _mapper.Map(request);
+ var product = mapper.Map(request);
- await _createAndSaveProductExecutor(product, cancellationToken);
+ await createAndSaveProductExecutor(product, cancellationToken);
var (name, categoryId, price, description) = request;
- await _mediator.Publish(ProductCreated.Of(request.Id, name, categoryId, price, description), cancellationToken);
+ await mediator.Publish(ProductCreated.Of(request.Id, name, categoryId, price, description), cancellationToken);
- _logger.LogInformation("Product a with ID: '{ProductId} created.'", request.Id);
+ logger.LogInformation("Product a with ID: '{ProductId} created.'", request.Id);
return new CreateProductResult(product.Id);
}
diff --git a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs
similarity index 91%
rename from src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs
rename to src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs
index 361e0eb..a4bbf10 100644
--- a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/CreateProductEndpoint.cs
@@ -6,9 +6,9 @@
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
-using Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
+using Shared.Abstractions.Web;
+using Shared.Web.Minimal.Extensions;
+using Shared.Web.ProblemDetail.HttpResults;
namespace Vertical.Slice.Template.Products.Features.CreatingProduct.v1;
@@ -65,4 +65,4 @@ CancellationToken CancellationToken
internal record CreateProductResponse(Guid Id);
// we can expect any value from the user for all reference types are nullable and we should do some validation in other levels (we use pure records mostly for dtos without needing validation)
-public record CreateProductRequest(string? Name, Guid CategoryId, decimal Price, string? Description);
+internal record CreateProductRequest(string? Name, Guid CategoryId, decimal Price, string? Description);
diff --git a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs
similarity index 87%
rename from src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs
rename to src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs
index 07863f5..bd4771d 100644
--- a/src/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/CreatingProduct/v1/ProductCreated.cs
@@ -1,6 +1,6 @@
using FluentValidation;
-using Vertical.Slice.Template.Shared.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
+using Shared.Core.Domain.Events;
+using Shared.Validation.Extensions;
namespace Vertical.Slice.Template.Products.Features.CreatingProduct.v1;
@@ -11,7 +11,7 @@ namespace Vertical.Slice.Template.Products.Features.CreatingProduct.v1;
// https://codeopinion.com/leaking-value-objects-from-your-domain/
// https://www.youtube.com/watch?v=CdanF8PWJng
// we don't pass value-objects and domains to our commands and events, just primitive types
-public record ProductCreated(Guid Id, string Name, Guid CategoryId, decimal Price, string? Description = null)
+internal record ProductCreated(Guid Id, string Name, Guid CategoryId, decimal Price, string? Description = null)
: DomainEvent
{
public static ProductCreated Of(Guid id, string? name, Guid categoryId, decimal price, string? description = null)
diff --git a/src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs b/src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs
similarity index 67%
rename from src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs
rename to src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs
index f9d1e66..bf8f9bd 100644
--- a/src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductById.cs
@@ -1,21 +1,21 @@
using AutoMapper;
using FluentValidation;
using Microsoft.EntityFrameworkCore;
+using Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Cache;
+using Shared.Core.Exceptions;
+using Shared.Core.Extensions;
+using Shared.EF.Extensions;
+using Shared.Validation.Extensions;
using Vertical.Slice.Template.Products.Dtos.v1;
using Vertical.Slice.Template.Products.Models;
using Vertical.Slice.Template.Products.ReadModel;
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Cache;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
-using Vertical.Slice.Template.Shared.Core.Extensions;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.EF.Extensions;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
namespace Vertical.Slice.Template.Products.Features.GettingProductById.v1;
-public record GetProductById(Guid Id) : CacheQuery
+internal record GetProductById(Guid Id) : CacheQuery
{
///
/// GetProductById query with validation.
@@ -41,29 +41,21 @@ public GetProductByIdValidator()
}
}
-internal class GetProductByIdHandler : IQueryHandler
+internal class GetProductByIdHandler(DbExecutors.GetProductByIdExecutor getProductByIdExecutor, IMapper mapper)
+ : IQueryHandler
{
- private readonly DbExecutors.GetProductByIdExecutor _getProductByIdExecutor;
- private readonly IMapper _mapper;
-
- public GetProductByIdHandler(DbExecutors.GetProductByIdExecutor getProductByIdExecutor, IMapper mapper)
- {
- _getProductByIdExecutor = getProductByIdExecutor;
- _mapper = mapper;
- }
-
public async Task Handle(GetProductById request, CancellationToken cancellationToken)
{
request.NotBeNull();
- var productReadModel = await _getProductByIdExecutor(request.Id, cancellationToken);
+ var productReadModel = await getProductByIdExecutor(request.Id, cancellationToken);
if (productReadModel is null)
{
throw new NotFoundException($"product with id {request.Id} not found");
}
- var productDto = _mapper.Map(productReadModel);
+ var productDto = mapper.Map(productReadModel);
return new GetProductByIdResult(productDto);
}
diff --git a/src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs b/src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs
similarity index 91%
rename from src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs
rename to src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs
index d0d98f5..0942788 100644
--- a/src/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/GettingProductById/v1/GetProductByIdEndpoint.cs
@@ -6,11 +6,10 @@
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
-using Vertical.Slice.Template.Products.Dtos;
+using Shared.Abstractions.Web;
+using Shared.Web.Minimal.Extensions;
+using Shared.Web.ProblemDetail.HttpResults;
using Vertical.Slice.Template.Products.Dtos.v1;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
-using Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
namespace Vertical.Slice.Template.Products.Features.GettingProductById.v1;
diff --git a/src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs b/src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs
similarity index 67%
rename from src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs
rename to src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs
index 61a9468..2823000 100644
--- a/src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPage.cs
@@ -1,21 +1,21 @@
using AutoMapper;
using FluentValidation;
using Microsoft.EntityFrameworkCore;
+using Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Extensions;
+using Shared.Core.Paging;
+using Shared.Validation.Extensions;
using Sieve.Services;
using Vertical.Slice.Template.Products.Dtos.v1;
using Vertical.Slice.Template.Products.Models;
using Vertical.Slice.Template.Products.ReadModel;
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Core.Paging;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
namespace Vertical.Slice.Template.Products.Features.GettingProductsByPage.v1;
-public record GetProductsByPage : PageQuery
+internal record GetProductsByPage : PageQuery
{
///
/// GetProductById query with validation.
@@ -32,7 +32,7 @@ public static GetProductsByPage Of(PageRequest pageRequest)
PageNumber = pageNumber,
PageSize = pageSize,
Filters = filters,
- SortOrder = sortOrder
+ SortOrder = sortOrder,
}
);
}
@@ -52,36 +52,25 @@ public GetProductsByPageValidator()
}
}
-internal class GetProductByPageHandler : IQueryHandler
+internal class GetProductByPageHandler(
+ DbExecutors.GetProductsExecutor getProductsExecutor,
+ ISieveProcessor sieveProcessor,
+ IMapper mapper
+) : IQueryHandler
{
- private readonly DbExecutors.GetProductsExecutor _getProductsExecutor;
- private readonly ISieveProcessor _sieveProcessor;
- private readonly IMapper _mapper;
-
- public GetProductByPageHandler(
- DbExecutors.GetProductsExecutor getProductsExecutor,
- ISieveProcessor sieveProcessor,
- IMapper mapper
- )
- {
- _getProductsExecutor = getProductsExecutor;
- _sieveProcessor = sieveProcessor;
- _mapper = mapper;
- }
-
public async Task Handle(GetProductsByPage request, CancellationToken cancellationToken)
{
request.NotBeNull();
- var query = _getProductsExecutor(cancellationToken);
+ var query = getProductsExecutor(cancellationToken);
var pageList = await query.ApplyPagingAsync(
request,
- _mapper.ConfigurationProvider,
- _sieveProcessor,
+ mapper.ConfigurationProvider,
+ sieveProcessor,
cancellationToken
);
- var result = pageList.MapTo(_mapper);
+ var result = pageList.MapTo(mapper);
return new GetProductsByPageResult(result);
}
diff --git a/src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs b/src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs
similarity index 93%
rename from src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs
rename to src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs
index e5b68df..17707ea 100644
--- a/src/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs
+++ b/src/App/Vertical.Slice.Template/Products/Features/GettingProductsByPage/v1/GetProductsByPageEndpoint.cs
@@ -5,10 +5,10 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Routing;
+using Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Web;
+using Shared.Web.Minimal.Extensions;
using Vertical.Slice.Template.Products.Dtos.v1;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
namespace Vertical.Slice.Template.Products.Features.GettingProductsByPage.v1;
diff --git a/src/Vertical.Slice.Template/Products/Models/Product.cs b/src/App/Vertical.Slice.Template/Products/Models/Product.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/Models/Product.cs
rename to src/App/Vertical.Slice.Template/Products/Models/Product.cs
diff --git a/src/Vertical.Slice.Template/Products/ProductConfigurations.cs b/src/App/Vertical.Slice.Template/Products/ProductConfigurations.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/ProductConfigurations.cs
rename to src/App/Vertical.Slice.Template/Products/ProductConfigurations.cs
diff --git a/src/Vertical.Slice.Template/Products/ProductMappingProfiles.cs b/src/App/Vertical.Slice.Template/Products/ProductMappingProfiles.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/ProductMappingProfiles.cs
rename to src/App/Vertical.Slice.Template/Products/ProductMappingProfiles.cs
diff --git a/src/Vertical.Slice.Template/Products/ReadModel/ProductReadModel.cs b/src/App/Vertical.Slice.Template/Products/ReadModel/ProductReadModel.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Products/ReadModel/ProductReadModel.cs
rename to src/App/Vertical.Slice.Template/Products/ReadModel/ProductReadModel.cs
diff --git a/src/Vertical.Slice.Template/Shared/CatalogsConfigurations.cs b/src/App/Vertical.Slice.Template/Shared/CatalogsConfigurations.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/CatalogsConfigurations.cs
rename to src/App/Vertical.Slice.Template/Shared/CatalogsConfigurations.cs
diff --git a/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs
new file mode 100644
index 0000000..6aae7d0
--- /dev/null
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs
@@ -0,0 +1,5 @@
+using Shared.Resiliency.Options;
+
+namespace Vertical.Slice.Template.Shared.Clients.Catalogs;
+
+public class CatalogsApiClientOptions : HttpClientOptions;
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs
similarity index 79%
rename from src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs
index a0f3273..db325f9 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsClient.cs
@@ -1,25 +1,16 @@
using AutoMapper;
using Catalogs.ApiClient;
+using Shared.Abstractions.Core.Paging;
+using Shared.Core.Exceptions;
+using Shared.Core.Extensions;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
using Vertical.Slice.Template.Shared.Clients.Catalogs.Dtos;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Core.Paging;
namespace Vertical.Slice.Template.Shared.Clients.Catalogs;
-public class CatalogsClient : ICatalogsClient
+public class CatalogsClient(ICatalogsApiClient catalogsApiClient, IMapper mapper) : ICatalogsClient
{
- private readonly ICatalogsApiClient _catalogsApiClient;
- private readonly IMapper _mapper;
-
- public CatalogsClient(ICatalogsApiClient catalogsApiClient, IMapper mapper)
- {
- _catalogsApiClient = catalogsApiClient;
- _mapper = mapper;
- }
-
public const string ClientName = "CatalogsClient";
public async Task CreateProductAsync(
@@ -34,7 +25,7 @@ CancellationToken cancellationToken
// https://github.com/App-vNext/Polly#post-execution-capturing-the-result-or-any-final-exception
// https://stackoverflow.com/questions/21097730/usage-of-ensuresuccessstatuscode-and-handling-of-httprequestexception-it-throws
// https: //github.com/App-vNext/Polly#step-1--specify-the--exceptionsfaults-you-want-the-policy-to-handle
- var response = await _catalogsApiClient.CreateProductAsync(
+ var response = await catalogsApiClient.CreateProductAsync(
new CreateProductRequest(
createProductClientDto.CategoryId,
createProductClientDto.Description,
@@ -70,7 +61,7 @@ CancellationToken cancellationToken
{
// https://stackoverflow.com/questions/21097730/usage-of-ensuresuccessstatuscode-and-handling-of-httprequestexception-it-throws
// https: //github.com/App-vNext/Polly#step-1--specify-the--exceptionsfaults-you-want-the-policy-to-handle
- var response = await _catalogsApiClient.GetProductsByPageAsync(
+ var response = await catalogsApiClient.GetProductsByPageAsync(
getProductsByPageClientDto.PageSize,
getProductsByPageClientDto.PageNumber,
getProductsByPageClientDto.Filters,
@@ -78,7 +69,7 @@ CancellationToken cancellationToken
cancellationToken
);
- var items = _mapper.Map>(response.Products!.Items);
+ var items = mapper.Map>(response.Products!.Items);
return PageList.Create(
items,
@@ -106,9 +97,9 @@ public async Task GetProductByIdAsync(Guid id, CancellationToken cancel
{
// https://stackoverflow.com/questions/21097730/usage-of-ensuresuccessstatuscode-and-handling-of-httprequestexception-it-throws
// https: //github.com/App-vNext/Polly#step-1--specify-the--exceptionsfaults-you-want-the-policy-to-handle
- var response = await _catalogsApiClient.GetProductByIdAsync(id, cancellationToken);
+ var response = await catalogsApiClient.GetProductByIdAsync(id, cancellationToken);
- var product = _mapper.Map(response.Product);
+ var product = mapper.Map(response.Product);
return product;
}
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/CreateProductClientDto.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/CreateProductClientDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/CreateProductClientDto.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/CreateProductClientDto.cs
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs
similarity index 71%
rename from src/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs
index 6a388c0..706a3e3 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/Dtos/GetGetProductsByPageClientDto.cs
@@ -1,4 +1,4 @@
-using Vertical.Slice.Template.Shared.Core.Paging;
+using Shared.Core.Paging;
namespace Vertical.Slice.Template.Shared.Clients.Catalogs.Dtos;
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs
similarity index 97%
rename from src/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs
index f286e7e..e41b086 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Catalogs/ICatalogsClient.cs
@@ -1,5 +1,5 @@
+using Shared.Abstractions.Core.Paging;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
using Vertical.Slice.Template.Shared.Clients.Catalogs.Dtos;
namespace Vertical.Slice.Template.Shared.Clients.Catalogs;
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/AddressClientDto.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/AddressClientDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/AddressClientDto.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/AddressClientDto.cs
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UserClientDto.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UserClientDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UserClientDto.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UserClientDto.cs
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UsersListPageClientDto.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UsersListPageClientDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UsersListPageClientDto.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/Dtos/UsersListPageClientDto.cs
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs
similarity index 83%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs
index 3a78a21..27954cd 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Users/IUsersHttpClient.cs
@@ -1,4 +1,4 @@
-using Vertical.Slice.Template.Shared.Core.Paging;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Users.Models;
namespace Vertical.Slice.Template.Shared.Clients.Users;
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs
similarity index 74%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs
index 6742498..29f6535 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClient.cs
@@ -3,29 +3,21 @@
using AutoMapper;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Options;
+using Shared.Core.Paging;
+using Shared.Web.Extensions;
using Vertical.Slice.Template.Shared.Clients.Users.Dtos;
-using Vertical.Slice.Template.Shared.Core.Paging;
-using Vertical.Slice.Template.Shared.Web.Extensions;
using Vertical.Slice.Template.Users.Models;
namespace Vertical.Slice.Template.Shared.Clients.Users;
-public class UsersHttpClient : IUsersHttpClient
+public class UsersHttpClient(
+ HttpClient httpClient,
+ IMapper mapper,
+ IOptions userHttpClientOptions
+)
+ : IUsersHttpClient
{
- private readonly HttpClient _httpClient;
- private readonly IMapper _mapper;
- private readonly UsersHttpClientOptions _userHttpClientOptions;
-
- public UsersHttpClient(
- HttpClient httpClient,
- IMapper mapper,
- IOptions userHttpClientOptions
- )
- {
- _httpClient = httpClient;
- _mapper = mapper;
- _userHttpClientOptions = userHttpClientOptions.Value;
- }
+ private readonly UsersHttpClientOptions _userHttpClientOptions = userHttpClientOptions.Value;
public async Task> GetAllUsersAsync(
PageRequest pageRequest,
@@ -40,7 +32,7 @@ public async Task> GetAllUsersAsync(
};
// https://github.com/App-vNext/Polly#handing-return-values-and-policytresult
- var httpResponse = await _httpClient.GetAsync(
+ var httpResponse = await httpClient.GetAsync(
$"{_userHttpClientOptions.UsersEndpoint}?{qb.ToQueryString().Value}",
cancellationToken
);
@@ -59,7 +51,7 @@ public async Task> GetAllUsersAsync(
var mod = usersListPage.Total % usersListPage.Limit;
var totalPageCount = (usersListPage.Total / usersListPage.Limit) + (mod == 0 ? 0 : 1);
- var items = _mapper.Map>(usersListPage.Users);
+ var items = mapper.Map>(usersListPage.Users);
var pageList = new PageList(items.ToList(), usersListPage.Skip, usersListPage.Limit, usersListPage.Total);
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs b/src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs
similarity index 80%
rename from src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs
rename to src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs
index 74b22a5..3d8891a 100644
--- a/src/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Clients/Users/UsersHttpClientOptions.cs
@@ -1,4 +1,4 @@
-using Vertical.Slice.Template.Shared.Resiliency.Options;
+using Shared.Resiliency.Options;
namespace Vertical.Slice.Template.Shared.Clients.Users;
diff --git a/src/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs
similarity index 71%
rename from src/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs
rename to src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs
index 64d73ef..47beb3d 100644
--- a/src/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContext.cs
@@ -1,17 +1,14 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore;
+using Shared.EF;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.EF;
namespace Vertical.Slice.Template.Shared.Data;
-public class CatalogsDbContext : EfDbContextBase
+public class CatalogsDbContext(DbContextOptions options) : EfDbContextBase(options)
{
public const string DefaultSchema = "catalog";
- public CatalogsDbContext(DbContextOptions options)
- : base(options) { }
-
public DbSet Products { get; set; } = default!;
protected override void OnModelCreating(ModelBuilder builder)
diff --git a/src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs
new file mode 100644
index 0000000..f77a59c
--- /dev/null
+++ b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs
@@ -0,0 +1,7 @@
+using Shared.EF;
+
+namespace Vertical.Slice.Template.Shared.Data;
+
+public class CatalogsDbContextDesignFactory()
+ : DbContextDesignFactoryBase(
+ $"{nameof(PostgresOptions)}:{nameof(PostgresOptions.ConnectionString)}");
diff --git a/src/App/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs
new file mode 100644
index 0000000..e62b0bd
--- /dev/null
+++ b/src/App/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs
@@ -0,0 +1,20 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using Shared.Abstractions.Persistence;
+
+namespace Vertical.Slice.Template.Shared.Data;
+
+public class CatalogsMigrationExecutor(CatalogsDbContext catalogsDbContext, ILogger logger)
+ : IMigrationExecutor
+{
+ public async Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ logger.LogInformation("Migration worker started");
+
+ logger.LogInformation("Updating catalog database...");
+
+ await catalogsDbContext.Database.MigrateAsync(cancellationToken: cancellationToken);
+
+ logger.LogInformation("Catalog database Updated");
+ }
+}
diff --git a/src/App/Vertical.Slice.Template/Shared/Data/GenericRepository.cs b/src/App/Vertical.Slice.Template/Shared/Data/GenericRepository.cs
new file mode 100644
index 0000000..f819c69
--- /dev/null
+++ b/src/App/Vertical.Slice.Template/Shared/Data/GenericRepository.cs
@@ -0,0 +1,6 @@
+using Shared.Core.Persistence.Ef;
+
+namespace Vertical.Slice.Template.Shared.Data;
+
+public class GenericRepository(CatalogsDbContext dbContext) : EfRepository(dbContext)
+ where T : class;
diff --git a/src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.Designer.cs b/src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.Designer.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.Designer.cs
rename to src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.Designer.cs
diff --git a/src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.cs b/src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.cs
rename to src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/20240821165201_InitialCatalogMigration.cs
diff --git a/src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/CatalogsDbContextModelSnapshot.cs b/src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/CatalogsDbContextModelSnapshot.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/CatalogsDbContextModelSnapshot.cs
rename to src/App/Vertical.Slice.Template/Shared/Data/Migrations/Catalogs/CatalogsDbContextModelSnapshot.cs
diff --git a/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/CatalogsDataSeeder.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/CatalogsDataSeeder.cs
new file mode 100644
index 0000000..8aed1b2
--- /dev/null
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/CatalogsDataSeeder.cs
@@ -0,0 +1,13 @@
+using Shared.Abstractions.Persistence.Ef;
+
+namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
+
+public class CatalogsDataSeeder : IDataSeeder
+{
+ public Task SeedAllAsync(CancellationToken cancellationToken)
+ {
+ return Task.CompletedTask;
+ }
+
+ public int Order => 1;
+}
diff --git a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs
similarity index 96%
rename from src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs
rename to src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs
index aa3c0e4..353c09c 100644
--- a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.HttpClient.cs
@@ -1,8 +1,8 @@
using Catalogs.ApiClient;
using Microsoft.AspNetCore.Builder;
+using Shared.Resiliency.Extensions;
using Vertical.Slice.Template.Shared.Clients.Catalogs;
using Vertical.Slice.Template.Shared.Clients.Users;
-using Vertical.Slice.Template.Shared.Resiliency.Extensions;
namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
diff --git a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs
similarity index 80%
rename from src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs
rename to src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs
index 0564f6e..675d2bb 100644
--- a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Infrastrcture.cs
@@ -1,18 +1,19 @@
using CorrelationId.DependencyInjection;
using MediatR;
using Microsoft.AspNetCore.Builder;
-using Vertical.Slice.Template.Shared.Abstractions.Ef.Repository;
-using Vertical.Slice.Template.Shared.Cache;
-using Vertical.Slice.Template.Shared.Cache.Behaviours;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.Abstractions.Persistence.Ef.Repository;
+using Shared.Cache;
+using Shared.Cache.Behaviours;
+using Shared.Core.Extensions;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.EF;
+using Shared.Logging;
+using Shared.Swagger;
+using Shared.Validation;
+using Shared.Validation.Extensions;
+using Shared.Web.Extensions;
+using Shared.Web.Extensions.WebApplicationBuilderExtensions;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.EF;
-using Vertical.Slice.Template.Shared.Logging;
-using Vertical.Slice.Template.Shared.Swagger;
-using Vertical.Slice.Template.Shared.Validation;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
-using Vertical.Slice.Template.Shared.Web.Extensions;
-using Vertical.Slice.Template.Shared.Web.Extensions.WebApplicationBuilderExtensions;
namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
diff --git a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs
similarity index 96%
rename from src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs
rename to src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs
index 6a89381..57b4412 100644
--- a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.ProblemDetails.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
-using Vertical.Slice.Template.Shared.Web.ProblemDetail;
+using Shared.Web.ProblemDetail;
namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
diff --git a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs
similarity index 71%
rename from src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs
rename to src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs
index adbe15f..adea5db 100644
--- a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Storage.cs
@@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Persistence;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.EF;
+using Shared.EF.Extensions;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.Shared.EF;
-using Vertical.Slice.Template.Shared.EF.Extensions;
-using Vertical.Slice.Template.Shared.Workers;
namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationBuilderExtensions;
@@ -25,12 +25,9 @@ public static void AddStorage(this WebApplicationBuilder builder)
{
builder.Services.AddPostgresDbContext();
- builder.Services.AddHostedService();
- builder.Services.AddHostedService();
-
// add migration and seeders dependencies
builder.Services.AddScoped();
- //services.AddScoped();
+ builder.Services.AddScoped();
}
}
}
diff --git a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs
similarity index 74%
rename from src/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs
rename to src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs
index 728bf50..3d15cb5 100644
--- a/src/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs
+++ b/src/App/Vertical.Slice.Template/Shared/Extensions/WebApplicationExtensions/WebApplicationExtensions.Infrastructure.cs
@@ -1,9 +1,6 @@
using CorrelationId;
using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.Hosting;
-using Serilog;
-using Vertical.Slice.Template.Shared.Web.Extensions;
-using Vertical.Slice.Template.Shared.Web.ProblemDetail.Middlewares.CaptureExceptionMiddleware;
+using Shared.Web.Extensions;
namespace Vertical.Slice.Template.Shared.Extensions.WebApplicationExtensions;
diff --git a/src/Vertical.Slice.Template/Users/Dtos/AddressDto.cs b/src/App/Vertical.Slice.Template/Users/Dtos/AddressDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/Dtos/AddressDto.cs
rename to src/App/Vertical.Slice.Template/Users/Dtos/AddressDto.cs
diff --git a/src/Vertical.Slice.Template/Users/Dtos/UserDto.cs b/src/App/Vertical.Slice.Template/Users/Dtos/UserDto.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/Dtos/UserDto.cs
rename to src/App/Vertical.Slice.Template/Users/Dtos/UserDto.cs
diff --git a/src/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs b/src/App/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs
similarity index 54%
rename from src/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs
rename to src/App/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs
index fe5ba16..465328d 100644
--- a/src/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs
+++ b/src/App/Vertical.Slice.Template/Users/GetUsers/GetUsers.cs
@@ -1,13 +1,13 @@
using AutoMapper;
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Core.Paging;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Shared.Clients.Users;
-using Vertical.Slice.Template.Shared.Core.Paging;
using Vertical.Slice.Template.Users.Dtos;
namespace Vertical.Slice.Template.Users.GetUsers;
-public record GetUsersByPage : PageQuery
+internal record GetUsersByPage : PageQuery
{
///
/// GetUsersByPage query with validation.
@@ -28,22 +28,14 @@ public static GetUsersByPage Of(PageRequest pageRequest)
}
}
-internal class GetUsersHandler : IQueryHandler
+internal class GetUsersHandler(IUsersHttpClient usersHttpClient, IMapper mapper)
+ : IQueryHandler
{
- private readonly IUsersHttpClient _usersHttpClient;
- private readonly IMapper _mapper;
-
- public GetUsersHandler(IUsersHttpClient usersHttpClient, IMapper mapper)
- {
- _usersHttpClient = usersHttpClient;
- _mapper = mapper;
- }
-
public async Task Handle(GetUsersByPage request, CancellationToken cancellationToken)
{
- var usersList = await _usersHttpClient.GetAllUsersAsync(request, cancellationToken);
+ var usersList = await usersHttpClient.GetAllUsersAsync(request, cancellationToken);
- var dtos = usersList.MapTo(u => _mapper.Map(u));
+ var dtos = usersList.MapTo(mapper.Map);
return new GetUsersByPageResult(dtos);
}
diff --git a/src/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs b/src/App/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs
similarity index 92%
rename from src/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs
rename to src/App/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs
index 20c991a..d51e344 100644
--- a/src/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs
+++ b/src/App/Vertical.Slice.Template/Users/GetUsers/GetUsersEndpoint.cs
@@ -5,9 +5,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Routing;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+using Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Web;
+using Shared.Web.Minimal.Extensions;
using Vertical.Slice.Template.Users.Dtos;
namespace Vertical.Slice.Template.Users.GetUsers;
diff --git a/src/Vertical.Slice.Template/Users/Models/Address.cs b/src/App/Vertical.Slice.Template/Users/Models/Address.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/Models/Address.cs
rename to src/App/Vertical.Slice.Template/Users/Models/Address.cs
diff --git a/src/Vertical.Slice.Template/Users/Models/User.cs b/src/App/Vertical.Slice.Template/Users/Models/User.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/Models/User.cs
rename to src/App/Vertical.Slice.Template/Users/Models/User.cs
diff --git a/src/Vertical.Slice.Template/Users/UsersConfigurations.cs b/src/App/Vertical.Slice.Template/Users/UsersConfigurations.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/UsersConfigurations.cs
rename to src/App/Vertical.Slice.Template/Users/UsersConfigurations.cs
diff --git a/src/Vertical.Slice.Template/Users/UsersMappingProfile.cs b/src/App/Vertical.Slice.Template/Users/UsersMappingProfile.cs
similarity index 100%
rename from src/Vertical.Slice.Template/Users/UsersMappingProfile.cs
rename to src/App/Vertical.Slice.Template/Users/UsersMappingProfile.cs
diff --git a/src/Vertical.Slice.Template/Vertical.Slice.Template.csproj b/src/App/Vertical.Slice.Template/Vertical.Slice.Template.csproj
similarity index 81%
rename from src/Vertical.Slice.Template/Vertical.Slice.Template.csproj
rename to src/App/Vertical.Slice.Template/Vertical.Slice.Template.csproj
index be20243..15bb057 100644
--- a/src/Vertical.Slice.Template/Vertical.Slice.Template.csproj
+++ b/src/App/Vertical.Slice.Template/Vertical.Slice.Template.csproj
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/src/Vertical.Slice.Template/readme.md b/src/App/Vertical.Slice.Template/readme.md
similarity index 100%
rename from src/Vertical.Slice.Template/readme.md
rename to src/App/Vertical.Slice.Template/readme.md
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheProviderType.cs b/src/Shared/Abstractions/Caching/CacheProviderType.cs
similarity index 51%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheProviderType.cs
rename to src/Shared/Abstractions/Caching/CacheProviderType.cs
index f40037d..85e52db 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheProviderType.cs
+++ b/src/Shared/Abstractions/Caching/CacheProviderType.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Caching;
+namespace Shared.Abstractions.Caching;
public enum CacheProviderType
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheSerializationType.cs b/src/Shared/Abstractions/Caching/CacheSerializationType.cs
similarity index 54%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheSerializationType.cs
rename to src/Shared/Abstractions/Caching/CacheSerializationType.cs
index 004f266..795b1ca 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/CacheSerializationType.cs
+++ b/src/Shared/Abstractions/Caching/CacheSerializationType.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Caching;
+namespace Shared.Abstractions.Caching;
public enum CacheSerializationType
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheQuery.cs b/src/Shared/Abstractions/Caching/ICacheQuery.cs
similarity index 59%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheQuery.cs
rename to src/Shared/Abstractions/Caching/ICacheQuery.cs
index 881275d..9a06e1b 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheQuery.cs
+++ b/src/Shared/Abstractions/Caching/ICacheQuery.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Core.CQRS;
-namespace Vertical.Slice.Template.Shared.Abstractions.Caching;
+namespace Shared.Abstractions.Caching;
public interface ICacheQuery : IQuery, ICacheRequest
where TResponse : class
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheRequest.cs b/src/Shared/Abstractions/Caching/ICacheRequest.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheRequest.cs
rename to src/Shared/Abstractions/Caching/ICacheRequest.cs
index 6089391..f459a18 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/ICacheRequest.cs
+++ b/src/Shared/Abstractions/Caching/ICacheRequest.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Caching;
+namespace Shared.Abstractions.Caching;
// Ref: https://anderly.com/2019/12/12/cross-cutting-concerns-with-mediatr-pipeline-behaviors/
// Works like FluentValidation with defining nested or separate class for our command or query
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/IInvalidateCacheRequest.cs b/src/Shared/Abstractions/Caching/IInvalidateCacheRequest.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Caching/IInvalidateCacheRequest.cs
rename to src/Shared/Abstractions/Caching/IInvalidateCacheRequest.cs
index 627b104..6c5e39d 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Caching/IInvalidateCacheRequest.cs
+++ b/src/Shared/Abstractions/Caching/IInvalidateCacheRequest.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Caching;
+namespace Shared.Abstractions.Caching;
public interface IInvalidateCacheRequest
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommand.cs b/src/Shared/Abstractions/Core/CQRS/ICommand.cs
similarity index 70%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommand.cs
rename to src/Shared/Abstractions/Core/CQRS/ICommand.cs
index 19f9ec0..e0c234d 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommand.cs
+++ b/src/Shared/Abstractions/Core/CQRS/ICommand.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+namespace Shared.Abstractions.Core.CQRS;
public interface ICommand : IRequest { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommandHandler.cs b/src/Shared/Abstractions/Core/CQRS/ICommandHandler.cs
similarity index 81%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommandHandler.cs
rename to src/Shared/Abstractions/Core/CQRS/ICommandHandler.cs
index dba150e..23ae83b 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/ICommandHandler.cs
+++ b/src/Shared/Abstractions/Core/CQRS/ICommandHandler.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+namespace Shared.Abstractions.Core.CQRS;
public interface ICommandHandler : IRequestHandler
where TCommand : ICommand { }
diff --git a/src/Shared/Abstractions/Core/CQRS/IPageQuery.cs b/src/Shared/Abstractions/Core/CQRS/IPageQuery.cs
new file mode 100644
index 0000000..d35d2f9
--- /dev/null
+++ b/src/Shared/Abstractions/Core/CQRS/IPageQuery.cs
@@ -0,0 +1,6 @@
+using Shared.Abstractions.Core.Paging;
+
+namespace Shared.Abstractions.Core.CQRS;
+
+public interface IPageQuery : IPageRequest, IQuery
+ where TResponse : class { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQuery.cs b/src/Shared/Abstractions/Core/CQRS/IQuery.cs
similarity index 78%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQuery.cs
rename to src/Shared/Abstractions/Core/CQRS/IQuery.cs
index 345be0a..79b0ddc 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQuery.cs
+++ b/src/Shared/Abstractions/Core/CQRS/IQuery.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+namespace Shared.Abstractions.Core.CQRS;
public interface IQuery : IRequest
where TResponse : class { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQueryHandler.cs b/src/Shared/Abstractions/Core/CQRS/IQueryHandler.cs
similarity index 86%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQueryHandler.cs
rename to src/Shared/Abstractions/Core/CQRS/IQueryHandler.cs
index 1e455ca..0a20b15 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IQueryHandler.cs
+++ b/src/Shared/Abstractions/Core/CQRS/IQueryHandler.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+namespace Shared.Abstractions.Core.CQRS;
public interface IQueryHandler : IRequestHandler
where TQuery : IQuery
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs b/src/Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs
similarity index 79%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs
index 934a8e3..9caf846 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IAggregatesDomainEventsRequestStore.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IAggregatesDomainEventsRequestStore
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs b/src/Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs
similarity index 83%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs
index c6a4f05..92033b3 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IDomainEvent.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
///
/// The domain event interface.
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs
similarity index 67%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs
index 0a4c29a..6dc1a7f 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventContext.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IDomainEventContext
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs
similarity index 59%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs
index 8731056..7ea75fb 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventHandler.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IDomainEventHandler : IEventHandler
where TEvent : IDomainEvent { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs
similarity index 76%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs
index a3989c8..3b3dde7 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventPublisher.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IDomainEventPublisher
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs
similarity index 59%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs
index b3a3b38..25bed3a 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IDomainEventsAccessor.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IDomainEventsAccessor
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEvent.cs b/src/Shared/Abstractions/Core/Domain/Events/IEvent.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEvent.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IEvent.cs
index 920bbe1..1b30780 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEvent.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IEvent.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
///
/// The event interface.
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEventHandler.cs b/src/Shared/Abstractions/Core/Domain/Events/IEventHandler.cs
similarity index 63%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEventHandler.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IEventHandler.cs
index 54305a1..024680d 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IEventHandler.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IEventHandler.cs
@@ -1,6 +1,6 @@
using MediatR;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IEventHandler : INotificationHandler
where TEvent : INotification { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs b/src/Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs
rename to src/Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs
index 8e5a301..74cb147 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs
+++ b/src/Shared/Abstractions/Core/Domain/Events/IHaveDomainEvents.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+namespace Shared.Abstractions.Core.Domain.Events;
public interface IHaveDomainEvents
{
diff --git a/src/Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs b/src/Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs
new file mode 100644
index 0000000..b906c42
--- /dev/null
+++ b/src/Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs
@@ -0,0 +1,3 @@
+namespace Shared.Abstractions.Core.Domain.Events;
+
+public interface IHaveNotificationEvent { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAggregate.cs b/src/Shared/Abstractions/Core/Domain/IAggregate.cs
similarity index 68%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAggregate.cs
rename to src/Shared/Abstractions/Core/Domain/IAggregate.cs
index 26dc80a..71f47c9 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAggregate.cs
+++ b/src/Shared/Abstractions/Core/Domain/IAggregate.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Core.Domain;
+using Shared.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IAggregate : IEntity, IHaveAggregate { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAuditableEntity.cs b/src/Shared/Abstractions/Core/Domain/IAuditableEntity.cs
similarity index 80%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAuditableEntity.cs
rename to src/Shared/Abstractions/Core/Domain/IAuditableEntity.cs
index 8cb5519..15986ba 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IAuditableEntity.cs
+++ b/src/Shared/Abstractions/Core/Domain/IAuditableEntity.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IAuditableEntity : IEntity, IHaveAudit { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IBusinessRule.cs b/src/Shared/Abstractions/Core/Domain/IBusinessRule.cs
similarity index 55%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IBusinessRule.cs
rename to src/Shared/Abstractions/Core/Domain/IBusinessRule.cs
index da0201a..1a10a42 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IBusinessRule.cs
+++ b/src/Shared/Abstractions/Core/Domain/IBusinessRule.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IBusinessRule
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IEntity.cs b/src/Shared/Abstractions/Core/Domain/IEntity.cs
similarity index 66%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IEntity.cs
rename to src/Shared/Abstractions/Core/Domain/IEntity.cs
index a3cd3b3..b56303b 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IEntity.cs
+++ b/src/Shared/Abstractions/Core/Domain/IEntity.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Core.Domain;
+using Shared.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IEntity : IHaveIdentity, IHaveCreator { }
diff --git a/src/Shared/Abstractions/Core/Domain/IHaveAggregate.cs b/src/Shared/Abstractions/Core/Domain/IHaveAggregate.cs
new file mode 100644
index 0000000..ce78a9b
--- /dev/null
+++ b/src/Shared/Abstractions/Core/Domain/IHaveAggregate.cs
@@ -0,0 +1,5 @@
+using Shared.Abstractions.Core.Domain.Events;
+
+namespace Shared.Abstractions.Core.Domain;
+
+public interface IHaveAggregate : IHaveDomainEvents, IHaveAggregateVersion { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs b/src/Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs
similarity index 84%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs
rename to src/Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs
index 8f4cd83..806f13d 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs
+++ b/src/Shared/Abstractions/Core/Domain/IHaveAggregateVersion.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IHaveAggregateVersion
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAudit.cs b/src/Shared/Abstractions/Core/Domain/IHaveAudit.cs
similarity index 63%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAudit.cs
rename to src/Shared/Abstractions/Core/Domain/IHaveAudit.cs
index c3b53de..0261730 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAudit.cs
+++ b/src/Shared/Abstractions/Core/Domain/IHaveAudit.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IHaveAudit : IHaveCreator
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveCreator.cs b/src/Shared/Abstractions/Core/Domain/IHaveCreator.cs
similarity index 58%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveCreator.cs
rename to src/Shared/Abstractions/Core/Domain/IHaveCreator.cs
index 0d49eb9..8bbd9a8 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveCreator.cs
+++ b/src/Shared/Abstractions/Core/Domain/IHaveCreator.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IHaveCreator
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveIdentity.cs b/src/Shared/Abstractions/Core/Domain/IHaveIdentity.cs
similarity index 72%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveIdentity.cs
rename to src/Shared/Abstractions/Core/Domain/IHaveIdentity.cs
index 3e26556..89aa53c 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveIdentity.cs
+++ b/src/Shared/Abstractions/Core/Domain/IHaveIdentity.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public interface IHaveIdentity : IHaveIdentity
{
diff --git a/src/Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs b/src/Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs
new file mode 100644
index 0000000..b9e1f10
--- /dev/null
+++ b/src/Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs
@@ -0,0 +1,3 @@
+namespace Shared.Abstractions.Core.Domain;
+
+public interface IHaveSoftDelete { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IIdentity.cs b/src/Shared/Abstractions/Core/Domain/IIdentity.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IIdentity.cs
rename to src/Shared/Abstractions/Core/Domain/IIdentity.cs
index ecf0876..e8f00e1 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IIdentity.cs
+++ b/src/Shared/Abstractions/Core/Domain/IIdentity.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
///
/// Super type for all Store.Services.Identity types with generic InternalCommandId.
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Identity.cs b/src/Shared/Abstractions/Core/Domain/Identity.cs
similarity index 86%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Identity.cs
rename to src/Shared/Abstractions/Core/Domain/Identity.cs
index 57ba211..6a78700 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Identity.cs
+++ b/src/Shared/Abstractions/Core/Domain/Identity.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+namespace Shared.Abstractions.Core.Domain;
public abstract record Identity
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageList.cs b/src/Shared/Abstractions/Core/Paging/IPageList.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageList.cs
rename to src/Shared/Abstractions/Core/Paging/IPageList.cs
index 5470621..c00bd19 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageList.cs
+++ b/src/Shared/Abstractions/Core/Paging/IPageList.cs
@@ -1,6 +1,6 @@
using AutoMapper;
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
+namespace Shared.Abstractions.Core.Paging;
public interface IPageList
where T : class
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageRequest.cs b/src/Shared/Abstractions/Core/Paging/IPageRequest.cs
similarity index 72%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageRequest.cs
rename to src/Shared/Abstractions/Core/Paging/IPageRequest.cs
index e978f3f..1b232ec 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Paging/IPageRequest.cs
+++ b/src/Shared/Abstractions/Core/Paging/IPageRequest.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
+namespace Shared.Abstractions.Core.Paging;
public interface IPageRequest
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IConnectionFactory.cs b/src/Shared/Abstractions/Persistence/Ef/IConnectionFactory.cs
similarity index 69%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/IConnectionFactory.cs
rename to src/Shared/Abstractions/Persistence/Ef/IConnectionFactory.cs
index 3690527..c0e91c5 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IConnectionFactory.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/IConnectionFactory.cs
@@ -1,6 +1,6 @@
using System.Data.Common;
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence.Ef;
public interface IConnectionFactory : IDisposable
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDataSeeder.cs b/src/Shared/Abstractions/Persistence/Ef/IDataSeeder.cs
similarity index 66%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDataSeeder.cs
rename to src/Shared/Abstractions/Persistence/Ef/IDataSeeder.cs
index 5e6d780..7689fba 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDataSeeder.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/IDataSeeder.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence.Ef;
public interface IDataSeeder
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbExecutors.cs b/src/Shared/Abstractions/Persistence/Ef/IDbExecutors.cs
similarity index 60%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbExecutors.cs
rename to src/Shared/Abstractions/Persistence/Ef/IDbExecutors.cs
index f4d5f33..b11d616 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbExecutors.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/IDbExecutors.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence.Ef;
public interface IDbExecutors
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbFacadeResolver.cs b/src/Shared/Abstractions/Persistence/Ef/IDbFacadeResolver.cs
similarity index 69%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbFacadeResolver.cs
rename to src/Shared/Abstractions/Persistence/Ef/IDbFacadeResolver.cs
index 67044f2..998cf1e 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IDbFacadeResolver.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/IDbFacadeResolver.cs
@@ -1,6 +1,6 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence.Ef;
public interface IDbFacadeResolver
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/ITxRequest.cs b/src/Shared/Abstractions/Persistence/Ef/ITxRequest.cs
similarity index 69%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/ITxRequest.cs
rename to src/Shared/Abstractions/Persistence/Ef/ITxRequest.cs
index bcb4a3f..5279b1f 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/ITxRequest.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/ITxRequest.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence.Ef;
// Ref: https://github.com/thangchung/clean-architecture-dotnet/blob/main/src/N8T.Core/Domain/Cqrs.cs
public interface ITxRequest { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IReadRepository.cs b/src/Shared/Abstractions/Persistence/Ef/Repository/IReadRepository.cs
similarity index 62%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IReadRepository.cs
rename to src/Shared/Abstractions/Persistence/Ef/Repository/IReadRepository.cs
index a972978..92217e2 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IReadRepository.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/Repository/IReadRepository.cs
@@ -1,6 +1,6 @@
using Ardalis.Specification;
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef.Repository;
+namespace Shared.Abstractions.Persistence.Ef.Repository;
public interface IReadRepository : IReadRepositoryBase
where T : class { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IRepository.cs b/src/Shared/Abstractions/Persistence/Ef/Repository/IRepository.cs
similarity index 66%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IRepository.cs
rename to src/Shared/Abstractions/Persistence/Ef/Repository/IRepository.cs
index 3448a08..b355361 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/Repository/IRepository.cs
+++ b/src/Shared/Abstractions/Persistence/Ef/Repository/IRepository.cs
@@ -1,6 +1,6 @@
using Ardalis.Specification;
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef.Repository;
+namespace Shared.Abstractions.Persistence.Ef.Repository;
// from Ardalis.Specification
public interface IRepository : IRepositoryBase
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IMigrationExecutor.cs b/src/Shared/Abstractions/Persistence/IMigrationExecutor.cs
similarity index 63%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Ef/IMigrationExecutor.cs
rename to src/Shared/Abstractions/Persistence/IMigrationExecutor.cs
index 5510f13..019052d 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Ef/IMigrationExecutor.cs
+++ b/src/Shared/Abstractions/Persistence/IMigrationExecutor.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Ef;
+namespace Shared.Abstractions.Persistence;
public interface IMigrationExecutor
{
diff --git a/src/Shared/Abstractions/Persistence/IMigrationManager.cs b/src/Shared/Abstractions/Persistence/IMigrationManager.cs
new file mode 100644
index 0000000..ceb4229
--- /dev/null
+++ b/src/Shared/Abstractions/Persistence/IMigrationManager.cs
@@ -0,0 +1,6 @@
+namespace Shared.Abstractions.Persistence;
+
+public interface IMigrationManager
+{
+ Task ExecuteAsync(CancellationToken cancellationToken);
+}
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpCommand.cs b/src/Shared/Abstractions/Web/IHttpCommand.cs
similarity index 94%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpCommand.cs
rename to src/Shared/Abstractions/Web/IHttpCommand.cs
index e040408..dc40fdd 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpCommand.cs
+++ b/src/Shared/Abstractions/Web/IHttpCommand.cs
@@ -2,7 +2,7 @@
using MediatR;
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpQuery.cs b/src/Shared/Abstractions/Web/IHttpQuery.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpQuery.cs
rename to src/Shared/Abstractions/Web/IHttpQuery.cs
index b6ff1ed..ef18849 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IHttpQuery.cs
+++ b/src/Shared/Abstractions/Web/IHttpQuery.cs
@@ -2,7 +2,7 @@
using MediatR;
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
// https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/deconstruct#user-defined-types
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IMinimalEndpoint.cs b/src/Shared/Abstractions/Web/IMinimalEndpoint.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/IMinimalEndpoint.cs
rename to src/Shared/Abstractions/Web/IMinimalEndpoint.cs
index 046bc50..e7b9f61 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IMinimalEndpoint.cs
+++ b/src/Shared/Abstractions/Web/IMinimalEndpoint.cs
@@ -4,7 +4,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
public interface IMinimalEndpoint
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IModuleConfiguration.cs b/src/Shared/Abstractions/Web/IModuleConfiguration.cs
similarity index 84%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/IModuleConfiguration.cs
rename to src/Shared/Abstractions/Web/IModuleConfiguration.cs
index fc9abc8..df95b6b 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IModuleConfiguration.cs
+++ b/src/Shared/Abstractions/Web/IModuleConfiguration.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
public interface IModuleConfiguration
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IProblemDetailMapper.cs b/src/Shared/Abstractions/Web/IProblemDetailMapper.cs
similarity index 61%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/IProblemDetailMapper.cs
rename to src/Shared/Abstractions/Web/IProblemDetailMapper.cs
index 040ab45..7a16e18 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/IProblemDetailMapper.cs
+++ b/src/Shared/Abstractions/Web/IProblemDetailMapper.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
public interface IProblemDetailMapper
{
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Web/ISharedModulesConfiguration.cs b/src/Shared/Abstractions/Web/ISharedModulesConfiguration.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Abstractions/Web/ISharedModulesConfiguration.cs
rename to src/Shared/Abstractions/Web/ISharedModulesConfiguration.cs
index af4f911..8b5e59a 100644
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Web/ISharedModulesConfiguration.cs
+++ b/src/Shared/Abstractions/Web/ISharedModulesConfiguration.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
-namespace Vertical.Slice.Template.Shared.Abstractions.Web;
+namespace Shared.Abstractions.Web;
public interface ISharedModulesConfiguration
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/Behaviours/CachingBehavior.cs b/src/Shared/Cache/Behaviours/CachingBehavior.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Cache/Behaviours/CachingBehavior.cs
rename to src/Shared/Cache/Behaviours/CachingBehavior.cs
index e615c99..55d2185 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/Behaviours/CachingBehavior.cs
+++ b/src/Shared/Cache/Behaviours/CachingBehavior.cs
@@ -2,9 +2,9 @@
using MediatR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache.Behaviours;
+namespace Shared.Cache.Behaviours;
// Ref: https://anderly.com/2019/12/12/cross-cutting-concerns-with-mediatr-pipeline-behaviors/
public class CachingBehavior : IPipelineBehavior
diff --git a/src/Vertical.Slice.Template.Shared/Cache/Behaviours/InvalidateCachingBehavior.cs b/src/Shared/Cache/Behaviours/InvalidateCachingBehavior.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Cache/Behaviours/InvalidateCachingBehavior.cs
rename to src/Shared/Cache/Behaviours/InvalidateCachingBehavior.cs
index 4041dd1..cd91b60 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/Behaviours/InvalidateCachingBehavior.cs
+++ b/src/Shared/Cache/Behaviours/InvalidateCachingBehavior.cs
@@ -2,9 +2,9 @@
using MediatR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache.Behaviours;
+namespace Shared.Cache.Behaviours;
public class InvalidateCachingBehavior : IPipelineBehavior
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Cache/CacheKey.cs b/src/Shared/Cache/CacheKey.cs
similarity index 72%
rename from src/Vertical.Slice.Template.Shared/Cache/CacheKey.cs
rename to src/Shared/Cache/CacheKey.cs
index 9fb3fb8..1422227 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/CacheKey.cs
+++ b/src/Shared/Cache/CacheKey.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Core.Reflection.Extensions;
+using Shared.Core.Reflection.Extensions;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public static class CacheKey
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/CacheOptions.cs b/src/Shared/Cache/CacheOptions.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Cache/CacheOptions.cs
rename to src/Shared/Cache/CacheOptions.cs
index 897fd6b..09a9723 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/CacheOptions.cs
+++ b/src/Shared/Cache/CacheOptions.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public class CacheOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/CacheQuery.cs b/src/Shared/Cache/CacheQuery.cs
similarity index 75%
rename from src/Vertical.Slice.Template.Shared/Cache/CacheQuery.cs
rename to src/Shared/Cache/CacheQuery.cs
index 428d38a..de89c47 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/CacheQuery.cs
+++ b/src/Shared/Cache/CacheQuery.cs
@@ -1,7 +1,7 @@
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Caching;
+using Shared.Abstractions.Core.CQRS;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public abstract record CacheQuery : ICacheQuery
where TRequest : IQuery
diff --git a/src/Vertical.Slice.Template.Shared/Cache/CacheRequest.cs b/src/Shared/Cache/CacheRequest.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Cache/CacheRequest.cs
rename to src/Shared/Cache/CacheRequest.cs
index 69c5354..24ffdc7 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/CacheRequest.cs
+++ b/src/Shared/Cache/CacheRequest.cs
@@ -1,7 +1,7 @@
using MediatR;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public abstract record CacheRequest : ICacheRequest
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Cache/DatabaseExtensions.cs b/src/Shared/Cache/DatabaseExtensions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Cache/DatabaseExtensions.cs
rename to src/Shared/Cache/DatabaseExtensions.cs
index f580f18..2a3c713 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/DatabaseExtensions.cs
+++ b/src/Shared/Cache/DatabaseExtensions.cs
@@ -3,7 +3,7 @@
using Newtonsoft.Json.Serialization;
using StackExchange.Redis;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public static class DatabaseExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/Extensions.cs b/src/Shared/Cache/Extensions.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Cache/Extensions.cs
rename to src/Shared/Cache/Extensions.cs
index 2851e40..56975d2 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/Extensions.cs
+++ b/src/Shared/Cache/Extensions.cs
@@ -1,12 +1,11 @@
using EasyCaching.Redis;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Options;
+using Shared.Abstractions.Caching;
+using Shared.Core.Extensions;
using StackExchange.Redis;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Web.Extensions;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public static class Extensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/InvalidateCacheRequest.cs b/src/Shared/Cache/InvalidateCacheRequest.cs
similarity index 83%
rename from src/Vertical.Slice.Template.Shared/Cache/InvalidateCacheRequest.cs
rename to src/Shared/Cache/InvalidateCacheRequest.cs
index 86a1c4a..70be410 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/InvalidateCacheRequest.cs
+++ b/src/Shared/Cache/InvalidateCacheRequest.cs
@@ -1,7 +1,7 @@
using MediatR;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public abstract class InvalidateCacheRequest : IInvalidateCacheRequest
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Cache/RedisOptions.cs b/src/Shared/Cache/RedisOptions.cs
similarity index 68%
rename from src/Vertical.Slice.Template.Shared/Cache/RedisOptions.cs
rename to src/Shared/Cache/RedisOptions.cs
index 58baf88..246152f 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/RedisOptions.cs
+++ b/src/Shared/Cache/RedisOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public class RedisOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Cache/StreamCacheRequest.cs b/src/Shared/Cache/StreamCacheRequest.cs
similarity index 83%
rename from src/Vertical.Slice.Template.Shared/Cache/StreamCacheRequest.cs
rename to src/Shared/Cache/StreamCacheRequest.cs
index 638d44f..2ae90e8 100644
--- a/src/Vertical.Slice.Template.Shared/Cache/StreamCacheRequest.cs
+++ b/src/Shared/Cache/StreamCacheRequest.cs
@@ -1,7 +1,7 @@
using MediatR;
-using Vertical.Slice.Template.Shared.Abstractions.Caching;
+using Shared.Abstractions.Caching;
-namespace Vertical.Slice.Template.Shared.Cache;
+namespace Shared.Cache;
public abstract class StreamCacheRequest : IStreamCacheRequest
where TRequest : IStreamRequest
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Aggregate.cs b/src/Shared/Core/Domain/Aggregate.cs
similarity index 88%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Aggregate.cs
rename to src/Shared/Core/Domain/Aggregate.cs
index ded2faf..e3b78e9 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Aggregate.cs
+++ b/src/Shared/Core/Domain/Aggregate.cs
@@ -1,10 +1,10 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
+using Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Core.Exceptions;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public abstract class Aggregate : Entity, IAggregate
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/AggregateFactory.cs b/src/Shared/Core/Domain/AggregateFactory.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/AggregateFactory.cs
rename to src/Shared/Core/Domain/AggregateFactory.cs
index de2612b..5d5d456 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/AggregateFactory.cs
+++ b/src/Shared/Core/Domain/AggregateFactory.cs
@@ -1,6 +1,6 @@
using System.Linq.Expressions;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public static class AggregateFactory
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/AggregateId.cs b/src/Shared/Core/Domain/AggregateId.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/AggregateId.cs
rename to src/Shared/Core/Domain/AggregateId.cs
index 3c8a001..c50eab0 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/AggregateId.cs
+++ b/src/Shared/Core/Domain/AggregateId.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public record AggregateId : Identity
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/AuditAggregate.cs b/src/Shared/Core/Domain/AuditAggregate.cs
similarity index 78%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/AuditAggregate.cs
rename to src/Shared/Core/Domain/AuditAggregate.cs
index 36e8f50..43f4a7b 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/AuditAggregate.cs
+++ b/src/Shared/Core/Domain/AuditAggregate.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public abstract class AuditAggregate : Aggregate, IAuditableEntity
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/AuditableEntity.cs b/src/Shared/Core/Domain/AuditableEntity.cs
similarity index 77%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/AuditableEntity.cs
rename to src/Shared/Core/Domain/AuditableEntity.cs
index d035811..80b2bfa 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/AuditableEntity.cs
+++ b/src/Shared/Core/Domain/AuditableEntity.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public class AuditableEntity : Entity, IAuditableEntity
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Entity.cs b/src/Shared/Core/Domain/Entity.cs
similarity index 77%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Entity.cs
rename to src/Shared/Core/Domain/Entity.cs
index dc3c8eb..2e830da 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Entity.cs
+++ b/src/Shared/Core/Domain/Entity.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public abstract class Entity : IEntity
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/EntityId.cs b/src/Shared/Core/Domain/EntityId.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/EntityId.cs
rename to src/Shared/Core/Domain/EntityId.cs
index 733666d..75e9479 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/EntityId.cs
+++ b/src/Shared/Core/Domain/EntityId.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Domain;
+namespace Shared.Core.Domain;
public record EntityId : Identity
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/AggregateDomainEventsStore.cs b/src/Shared/Core/Domain/Events/AggregateDomainEventsStore.cs
similarity index 78%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Events/AggregateDomainEventsStore.cs
rename to src/Shared/Core/Domain/Events/AggregateDomainEventsStore.cs
index fee8f4f..a4b706b 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/AggregateDomainEventsStore.cs
+++ b/src/Shared/Core/Domain/Events/AggregateDomainEventsStore.cs
@@ -1,7 +1,7 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.Core.Domain.Events;
+namespace Shared.Core.Domain.Events;
public class AggregatesDomainEventsStore : IAggregatesDomainEventsRequestStore
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEvent.cs b/src/Shared/Core/Domain/Events/DomainEvent.cs
similarity index 74%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEvent.cs
rename to src/Shared/Core/Domain/Events/DomainEvent.cs
index ba0a95f..09fa685 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEvent.cs
+++ b/src/Shared/Core/Domain/Events/DomainEvent.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.Core.Domain.Events;
+namespace Shared.Core.Domain.Events;
public record DomainEvent : Event, IDomainEvent
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventAccessor.cs b/src/Shared/Core/Domain/Events/DomainEventAccessor.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventAccessor.cs
rename to src/Shared/Core/Domain/Events/DomainEventAccessor.cs
index e03d051..c2d7c61 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventAccessor.cs
+++ b/src/Shared/Core/Domain/Events/DomainEventAccessor.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.Core.Domain.Events;
+namespace Shared.Core.Domain.Events;
public class DomainEventAccessor : IDomainEventsAccessor
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventPublisher.cs b/src/Shared/Core/Domain/Events/DomainEventPublisher.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventPublisher.cs
rename to src/Shared/Core/Domain/Events/DomainEventPublisher.cs
index fc1f861..8a22274 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/DomainEventPublisher.cs
+++ b/src/Shared/Core/Domain/Events/DomainEventPublisher.cs
@@ -1,9 +1,9 @@
using MediatR;
using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Core.Extensions;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Core.Extensions;
-namespace Vertical.Slice.Template.Shared.Core.Domain.Events;
+namespace Shared.Core.Domain.Events;
public class DomainEventPublisher : IDomainEventPublisher
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/Event.cs b/src/Shared/Core/Domain/Events/Event.cs
similarity index 69%
rename from src/Vertical.Slice.Template.Shared/Core/Domain/Events/Event.cs
rename to src/Shared/Core/Domain/Events/Event.cs
index 197dfab..200b3bb 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Domain/Events/Event.cs
+++ b/src/Shared/Core/Domain/Events/Event.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.Core.Domain.Events;
+namespace Shared.Core.Domain.Events;
public record Event : IEvent
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/AppException.cs b/src/Shared/Core/Exceptions/AppException.cs
similarity index 83%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/AppException.cs
rename to src/Shared/Core/Exceptions/AppException.cs
index b2eacf1..9791064 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/AppException.cs
+++ b/src/Shared/Core/Exceptions/AppException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class AppException : CustomException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/BadRequestException.cs b/src/Shared/Core/Exceptions/BadRequestException.cs
similarity index 81%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/BadRequestException.cs
rename to src/Shared/Core/Exceptions/BadRequestException.cs
index ae429db..59858e2 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/BadRequestException.cs
+++ b/src/Shared/Core/Exceptions/BadRequestException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class BadRequestException : CustomException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/BusinessRuleValidationException.cs b/src/Shared/Core/Exceptions/BusinessRuleValidationException.cs
similarity index 79%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/BusinessRuleValidationException.cs
rename to src/Shared/Core/Exceptions/BusinessRuleValidationException.cs
index a904536..95ed337 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/BusinessRuleValidationException.cs
+++ b/src/Shared/Core/Exceptions/BusinessRuleValidationException.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class BusinessRuleValidationException : DomainException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/ConflictException.cs b/src/Shared/Core/Exceptions/ConflictException.cs
similarity index 80%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/ConflictException.cs
rename to src/Shared/Core/Exceptions/ConflictException.cs
index 747ba02..ffe4974 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/ConflictException.cs
+++ b/src/Shared/Core/Exceptions/ConflictException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class ConflictException : CustomException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/CustomException.cs b/src/Shared/Core/Exceptions/CustomException.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/CustomException.cs
rename to src/Shared/Core/Exceptions/CustomException.cs
index 7bf20b1..c30afa3 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/CustomException.cs
+++ b/src/Shared/Core/Exceptions/CustomException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class CustomException : Exception
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/DomainException.cs b/src/Shared/Core/Exceptions/DomainException.cs
similarity index 86%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/DomainException.cs
rename to src/Shared/Core/Exceptions/DomainException.cs
index f2630f4..34437d0 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/DomainException.cs
+++ b/src/Shared/Core/Exceptions/DomainException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
///
/// Exception type for domain exceptions.
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/HttpResponseException.cs b/src/Shared/Core/Exceptions/HttpResponseException.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/HttpResponseException.cs
rename to src/Shared/Core/Exceptions/HttpResponseException.cs
index 24cbdb6..dc55400 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/HttpResponseException.cs
+++ b/src/Shared/Core/Exceptions/HttpResponseException.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
// https://stackoverflow.com/questions/21097730/usage-of-ensuresuccessstatuscode-and-handling-of-httprequestexception-it-throws
public class HttpResponseException : CustomException
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/NotFoundException.cs b/src/Shared/Core/Exceptions/NotFoundException.cs
similarity index 80%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/NotFoundException.cs
rename to src/Shared/Core/Exceptions/NotFoundException.cs
index 5476b3a..149abeb 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/NotFoundException.cs
+++ b/src/Shared/Core/Exceptions/NotFoundException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class NotFoundException : CustomException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Exceptions/ValidationException.cs b/src/Shared/Core/Exceptions/ValidationException.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Core/Exceptions/ValidationException.cs
rename to src/Shared/Core/Exceptions/ValidationException.cs
index 610eabd..14e1dee 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Exceptions/ValidationException.cs
+++ b/src/Shared/Core/Exceptions/ValidationException.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Core.Exceptions;
+namespace Shared.Core.Exceptions;
public class ValidationException : CustomException
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ConfigurationExtensions.cs b/src/Shared/Core/Extensions/ConfigurationExtensions.cs
similarity index 72%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/ConfigurationExtensions.cs
rename to src/Shared/Core/Extensions/ConfigurationExtensions.cs
index bf724cc..a9b6e36 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ConfigurationExtensions.cs
+++ b/src/Shared/Core/Extensions/ConfigurationExtensions.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Configuration;
-namespace Vertical.Slice.Template.Shared.Core.Extensions;
+namespace Shared.Core.Extensions;
///
/// Static helper class for .
@@ -12,9 +12,14 @@ public static class ConfigurationExtensions
///
/// The given bind model.
/// The configuration instance to bind.
- /// The configuration section
+ /// The configuration section.
+ ///
/// The new instance of .
- public static TOptions BindOptions(this IConfiguration configuration, string section)
+ public static TOptions BindOptions(
+ this IConfiguration configuration,
+ string section,
+ Action? configurator = null
+ )
where TOptions : new()
{
// note: with using Get<>() if there is no configuration in appsettings it just returns default value (null) for the configuration type
@@ -25,6 +30,8 @@ public static TOptions BindOptions(this IConfiguration configuration,
var optionsSection = configuration.GetSection(section);
optionsSection.Bind(options);
+ configurator?.Invoke(options);
+
return options;
}
@@ -33,10 +40,14 @@ public static TOptions BindOptions(this IConfiguration configuration,
///
/// The given bind model.
/// The configuration instance to bind.
+ ///
/// The new instance of .
- public static TOptions BindOptions(this IConfiguration configuration)
+ public static TOptions BindOptions(
+ this IConfiguration configuration,
+ Action? configurator = null
+ )
where TOptions : new()
{
- return BindOptions(configuration, typeof(TOptions).Name);
+ return BindOptions(configuration, typeof(TOptions).Name, configurator);
}
}
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.CoreRegistrations.cs b/src/Shared/Core/Extensions/DependencyInjectionExtensions.cs
similarity index 50%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.CoreRegistrations.cs
rename to src/Shared/Core/Extensions/DependencyInjectionExtensions.cs
index d159c95..13b23c0 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.CoreRegistrations.cs
+++ b/src/Shared/Core/Extensions/DependencyInjectionExtensions.cs
@@ -1,28 +1,33 @@
using System.Reflection;
using Polly;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Core.Domain.Events;
+using Shared.Core.Paging;
+using Shared.Core.Persistence.Extensions;
+using Shared.Core.Reflection;
using Sieve.Services;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Abstractions.Ef.Repository;
-using Vertical.Slice.Template.Shared.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Core.Ef;
-using Vertical.Slice.Template.Shared.Core.Paging;
-namespace Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
+namespace Shared.Core.Extensions;
-public static partial class ServiceCollectionExtensions
+public static class DependencyInjectionExtensions
{
public static IServiceCollection AddCore(this IServiceCollection services, params Assembly[] assembliesToScan)
{
- var scanAssemblies = assembliesToScan.Any() ? assembliesToScan : new[] { Assembly.GetCallingAssembly() };
+ var assemblies =
+ assembliesToScan.Length != 0
+ ? assembliesToScan
+ : ReflectionUtilities.GetReferencedAssemblies(Assembly.GetCallingAssembly()).Distinct().ToArray();
+
services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddScoped();
- services.ScanAndRegisterDbExecutors(scanAssemblies);
- var policy = Policy.Handle().RetryAsync(2);
+ services.AddPersistenceCore(assemblies);
+
+ var policy = Policy.Handle().RetryAsync(2);
services.AddSingleton(policy);
return services;
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/QueryableExtensions.cs b/src/Shared/Core/Extensions/QueryableExtensions.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/QueryableExtensions.cs
rename to src/Shared/Core/Extensions/QueryableExtensions.cs
index 14befe8..864db33 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/QueryableExtensions.cs
+++ b/src/Shared/Core/Extensions/QueryableExtensions.cs
@@ -1,12 +1,12 @@
using System.Linq.Expressions;
using AutoMapper;
using AutoMapper.QueryableExtensions;
+using Shared.Abstractions.Core.Paging;
+using Shared.Core.Paging;
using Sieve.Models;
using Sieve.Services;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
-using Vertical.Slice.Template.Shared.Core.Paging;
-namespace Vertical.Slice.Template.Shared.Core.Extensions;
+namespace Shared.Core.Extensions;
// we should not operation related to Ef or Mongo here and we should design as general with IQueryable to work with any providers
public static class QueryableExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs
similarity index 81%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs
rename to src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs
index 343d102..1077dbb 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs
+++ b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.DbExecutorExtensions.cs
@@ -1,8 +1,8 @@
using System.Reflection;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Core.Reflection.Extensions;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Reflection.Extensions;
-namespace Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
+namespace Shared.Core.Extensions.ServiceCollectionsExtensions;
public static partial class ServiceCollectionExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs
similarity index 99%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs
rename to src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs
index b25d0f6..2f1434c 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs
+++ b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Dependency.cs
@@ -1,7 +1,7 @@
using System.Reflection;
using Microsoft.Extensions.DependencyInjection.Extensions;
-namespace Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
+namespace Shared.Core.Extensions.ServiceCollectionsExtensions;
public static partial class ServiceCollectionExtensions
{
diff --git a/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs
new file mode 100644
index 0000000..4a4bee8
--- /dev/null
+++ b/src/Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs
@@ -0,0 +1,109 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
+
+namespace Shared.Core.Extensions.ServiceCollectionsExtensions;
+
+public static partial class ServiceCollectionExtensions
+{
+ public static IServiceCollection AddConfigurationOptions(
+ this IServiceCollection services,
+ string? key = null,
+ Action? configurator = null
+ )
+ where T : class
+ {
+ var optionBuilder = services.AddOptions().BindConfiguration(key ?? typeof(T).Name);
+
+ if (configurator is not null)
+ {
+ optionBuilder = optionBuilder.Configure(configurator);
+ }
+
+ services.TryAddSingleton(x => x.GetRequiredService>().Value);
+
+ return services;
+ }
+
+ public static IServiceCollection AddValidationOptions(
+ this IServiceCollection services,
+ Action? configurator = null
+ )
+ where T : class
+ {
+ var key = typeof(T).Name;
+
+ return AddValidatedOptions(services, key, RequiredConfigurationValidator.Validate, configurator);
+ }
+
+ public static IServiceCollection AddValidationOptions(
+ this IServiceCollection services,
+ string? key = null,
+ Action? configurator = null
+ )
+ where T : class
+ {
+ return AddValidatedOptions(
+ services,
+ key ?? typeof(T).Name,
+ RequiredConfigurationValidator.Validate,
+ configurator
+ );
+ }
+
+ public static IServiceCollection AddValidatedOptions(
+ this IServiceCollection services,
+ string? key = null,
+ Func? validator = null,
+ Action? configurator = null
+ )
+ where T : class
+ {
+ validator ??= RequiredConfigurationValidator.Validate;
+
+ // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options
+ // https://thecodeblogger.com/2021/04/21/options-pattern-in-net-ioptions-ioptionssnapshot-ioptionsmonitor/
+ // https://code-maze.com/aspnet-configuration-options/
+ // https://code-maze.com/aspnet-configuration-options-validation/
+ // https://dotnetdocs.ir/Post/42/difference-between-ioptions-ioptionssnapshot-and-ioptionsmonitor
+ // https://andrewlock.net/adding-validation-to-strongly-typed-configuration-objects-in-dotnet-6/
+
+ var optionBuilder = services.AddOptions().BindConfiguration(key ?? typeof(T).Name);
+
+ if (configurator is not null)
+ {
+ // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/#configure-options-with-a-delegate
+ optionBuilder = optionBuilder.Configure(configurator);
+ }
+
+ optionBuilder.Validate(validator);
+
+ // IOptions itself registered as singleton
+ services.TryAddSingleton(x => x.GetRequiredService>().Value);
+
+ return services;
+ }
+}
+
+public static class RequiredConfigurationValidator
+{
+ public static bool Validate(T arg)
+ where T : class
+ {
+ var requiredProperties = typeof(T)
+ .GetProperties(BindingFlags.Public | BindingFlags.Instance)
+ .Where(x => Attribute.IsDefined(x, typeof(RequiredMemberAttribute)));
+
+ foreach (var requiredProperty in requiredProperties)
+ {
+ var propertyValue = requiredProperty.GetValue(arg);
+ if (propertyValue is null)
+ {
+ throw new System.Exception($"Required property '{requiredProperty.Name}' was null");
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ValidationExtensions.cs b/src/Shared/Core/Extensions/ValidationExtensions.cs
similarity index 99%
rename from src/Vertical.Slice.Template.Shared/Core/Extensions/ValidationExtensions.cs
rename to src/Shared/Core/Extensions/ValidationExtensions.cs
index eb3707f..a13029c 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ValidationExtensions.cs
+++ b/src/Shared/Core/Extensions/ValidationExtensions.cs
@@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
-namespace Vertical.Slice.Template.Shared.Core.Extensions;
+namespace Shared.Core.Extensions;
// https://dev.to/lambdasharp/c-asserting-a-value-is-not-null-in-null-aware-code-f8m
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/nullable-analysis
diff --git a/src/Vertical.Slice.Template.Shared/Core/Id/IdGenerator.cs b/src/Shared/Core/Id/IdGenerator.cs
similarity index 71%
rename from src/Vertical.Slice.Template.Shared/Core/Id/IdGenerator.cs
rename to src/Shared/Core/Id/IdGenerator.cs
index f7ecbc1..ce37ba7 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Id/IdGenerator.cs
+++ b/src/Shared/Core/Id/IdGenerator.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Core.Id;
+namespace Shared.Core.Id;
public static class IdGenerator
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Paging/ApplicationSieveProcessor.cs b/src/Shared/Core/Paging/ApplicationSieveProcessor.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/Core/Paging/ApplicationSieveProcessor.cs
rename to src/Shared/Core/Paging/ApplicationSieveProcessor.cs
index 77a8b19..a56a92e 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Paging/ApplicationSieveProcessor.cs
+++ b/src/Shared/Core/Paging/ApplicationSieveProcessor.cs
@@ -3,7 +3,7 @@
using Sieve.Models;
using Sieve.Services;
-namespace Vertical.Slice.Template.Shared.Core.Paging;
+namespace Shared.Core.Paging;
// https://github.com/Biarity/Sieve#modular-fluent-api-configuration
public class ApplicationSieveProcessor : SieveProcessor
diff --git a/src/Vertical.Slice.Template.Shared/Core/Paging/PageList.cs b/src/Shared/Core/Paging/PageList.cs
similarity index 91%
rename from src/Vertical.Slice.Template.Shared/Core/Paging/PageList.cs
rename to src/Shared/Core/Paging/PageList.cs
index 6cc3aa4..41b1327 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Paging/PageList.cs
+++ b/src/Shared/Core/Paging/PageList.cs
@@ -1,7 +1,7 @@
using AutoMapper;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Core.Paging;
-namespace Vertical.Slice.Template.Shared.Core.Paging;
+namespace Shared.Core.Paging;
public record PageList(IReadOnlyList Items, int PageNumber, int PageSize, int TotalCount) : IPageList
where T : class
diff --git a/src/Vertical.Slice.Template.Shared/Core/Paging/PageQuery.cs b/src/Shared/Core/Paging/PageQuery.cs
similarity index 72%
rename from src/Vertical.Slice.Template.Shared/Core/Paging/PageQuery.cs
rename to src/Shared/Core/Paging/PageQuery.cs
index 32a1d30..e5b32e3 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Paging/PageQuery.cs
+++ b/src/Shared/Core/Paging/PageQuery.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
+using Shared.Abstractions.Core.CQRS;
-namespace Vertical.Slice.Template.Shared.Core.Paging;
+namespace Shared.Core.Paging;
// https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records#characteristics-of-records
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record
diff --git a/src/Vertical.Slice.Template.Shared/Core/Paging/PageRequest.cs b/src/Shared/Core/Paging/PageRequest.cs
similarity index 94%
rename from src/Vertical.Slice.Template.Shared/Core/Paging/PageRequest.cs
rename to src/Shared/Core/Paging/PageRequest.cs
index 3f48c86..bd480af 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Paging/PageRequest.cs
+++ b/src/Shared/Core/Paging/PageRequest.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
+using Shared.Abstractions.Core.Paging;
-namespace Vertical.Slice.Template.Shared.Core.Paging;
+namespace Shared.Core.Paging;
// https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records#characteristics-of-records
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record
diff --git a/src/Vertical.Slice.Template.Shared/Core/Ef/EfRepository.cs b/src/Shared/Core/Persistence/Ef/EfRepository.cs
similarity index 75%
rename from src/Vertical.Slice.Template.Shared/Core/Ef/EfRepository.cs
rename to src/Shared/Core/Persistence/Ef/EfRepository.cs
index 2b555d9..4fc841e 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Ef/EfRepository.cs
+++ b/src/Shared/Core/Persistence/Ef/EfRepository.cs
@@ -1,8 +1,8 @@
using Ardalis.Specification.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
-using Vertical.Slice.Template.Shared.Abstractions.Ef.Repository;
+using Shared.Abstractions.Persistence.Ef.Repository;
-namespace Vertical.Slice.Template.Shared.Core.Ef;
+namespace Shared.Core.Persistence.Ef;
// inherit from Ardalis.Specification type
public class EfRepository : RepositoryBase, IReadRepository, IRepository
diff --git a/src/Shared/Core/Persistence/Extensions/DbExecutorRegistrationsExtensions.cs b/src/Shared/Core/Persistence/Extensions/DbExecutorRegistrationsExtensions.cs
new file mode 100644
index 0000000..5a95575
--- /dev/null
+++ b/src/Shared/Core/Persistence/Extensions/DbExecutorRegistrationsExtensions.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Reflection.Extensions;
+
+namespace Shared.Core.Persistence.Extensions;
+
+internal static class DbExecutorRegistrationsExtensions
+{
+ internal static IServiceCollection ScanAndRegisterDbExecutors(
+ this IServiceCollection services,
+ params Assembly[] assembliesToScan
+ )
+ {
+ var dbExecutors = assembliesToScan
+ .SelectMany(x => x.GetLoadableTypes())
+ .Where(t =>
+ t!.IsClass
+ && !t.IsAbstract
+ && !t.IsGenericType
+ && !t.IsInterface
+ && t.GetConstructor(Type.EmptyTypes) != null
+ && typeof(IDbExecutors).IsAssignableFrom(t)
+ )
+ .ToList();
+
+ foreach (var dbExecutor in CollectionsMarshal.AsSpan(dbExecutors))
+ {
+ var instantiatedType = (IDbExecutors)Activator.CreateInstance(dbExecutor)!;
+ instantiatedType.Register(services);
+ }
+
+ return services;
+ }
+}
diff --git a/src/Shared/Core/Persistence/Extensions/DependencyInjectionExtensions.cs b/src/Shared/Core/Persistence/Extensions/DependencyInjectionExtensions.cs
new file mode 100644
index 0000000..77dc85c
--- /dev/null
+++ b/src/Shared/Core/Persistence/Extensions/DependencyInjectionExtensions.cs
@@ -0,0 +1,20 @@
+using System.Reflection;
+using Shared.Abstractions.Persistence;
+
+namespace Shared.Core.Persistence.Extensions;
+
+internal static class DependencyInjectionExtensions
+{
+ internal static IServiceCollection AddPersistenceCore(
+ this IServiceCollection services,
+ params Assembly[] assembliesToScan
+ )
+ {
+ services.ScanAndRegisterDbExecutors(assembliesToScan);
+
+ services.AddHostedService();
+ services.AddScoped();
+
+ return services;
+ }
+}
diff --git a/src/Shared/Core/Persistence/MigrationManager.cs b/src/Shared/Core/Persistence/MigrationManager.cs
new file mode 100644
index 0000000..e22b4d8
--- /dev/null
+++ b/src/Shared/Core/Persistence/MigrationManager.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Logging;
+using Shared.Abstractions.Persistence;
+
+namespace Shared.Core.Persistence;
+
+// because our migration should apply first we should apply migration before running all background services with our MigrationManager and before `app.RunAsync()` for running host and workers
+public class MigrationManager(
+ IServiceScopeFactory serviceScopeFactory,
+ ILogger logger,
+ IWebHostEnvironment environment
+) : IMigrationManager
+{
+ private readonly IWebHostEnvironment _environment = environment;
+
+ public async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ // https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
+ // https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
+ using var serviceScope = serviceScopeFactory.CreateScope();
+ var migrations = serviceScope.ServiceProvider.GetServices();
+
+ foreach (var migration in migrations)
+ {
+ logger.LogInformation("Migration '{Migration}' started...", migrations.GetType().Name);
+ await migration.ExecuteAsync(stoppingToken);
+ logger.LogInformation("Migration '{Migration}' ended...", migration.GetType().Name);
+ }
+ }
+}
diff --git a/src/Shared/Core/Persistence/SeedWorker.cs b/src/Shared/Core/Persistence/SeedWorker.cs
new file mode 100644
index 0000000..d18abea
--- /dev/null
+++ b/src/Shared/Core/Persistence/SeedWorker.cs
@@ -0,0 +1,45 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Shared.Abstractions.Persistence.Ef;
+
+namespace Shared.Core.Persistence;
+
+// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
+// Hint: we can't guarantee execution order of our seeder, and because our migration should apply first we should apply migration before running all background services with our MigrationManager and before `app.RunAsync()` for running host and workers
+public class SeedWorker(
+ IServiceScopeFactory serviceScopeFactory,
+ ILogger logger,
+ IWebHostEnvironment webHostEnvironment
+) : BackgroundService
+{
+ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ if (!webHostEnvironment.IsEnvironment("test"))
+ {
+ logger.LogInformation("Seed worker started");
+
+ // https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
+ // https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
+ using var serviceScope = serviceScopeFactory.CreateScope();
+ var seeders = serviceScope.ServiceProvider.GetServices();
+
+ foreach (var seeder in seeders.OrderBy(x => x.Order))
+ {
+ logger.LogInformation("Seeding '{Seed}' started...", seeder.GetType().Name);
+ await seeder.SeedAllAsync(cancellationToken);
+ logger.LogInformation("Seeding '{Seed}' ended...", seeder.GetType().Name);
+ }
+ }
+ }
+
+ public override Task StopAsync(CancellationToken cancellationToken)
+ {
+ if (!webHostEnvironment.IsEnvironment("test"))
+ {
+ logger.LogInformation("Seed worker stopped");
+ }
+
+ return base.StopAsync(cancellationToken);
+ }
+}
diff --git a/src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/AssemblyExtensions.cs b/src/Shared/Core/Reflection/Extensions/AssemblyExtensions.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/AssemblyExtensions.cs
rename to src/Shared/Core/Reflection/Extensions/AssemblyExtensions.cs
index a2e9df3..0ff66da 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/AssemblyExtensions.cs
+++ b/src/Shared/Core/Reflection/Extensions/AssemblyExtensions.cs
@@ -1,6 +1,6 @@
using System.Reflection;
-namespace Vertical.Slice.Template.Shared.Core.Reflection.Extensions;
+namespace Shared.Core.Reflection.Extensions;
public static class AssemblyExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/TypeExtensions.cs b/src/Shared/Core/Reflection/Extensions/TypeExtensions.cs
similarity index 99%
rename from src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/TypeExtensions.cs
rename to src/Shared/Core/Reflection/Extensions/TypeExtensions.cs
index e3ae7c6..90008ac 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Reflection/Extensions/TypeExtensions.cs
+++ b/src/Shared/Core/Reflection/Extensions/TypeExtensions.cs
@@ -3,9 +3,9 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.DependencyInjection.Extensions;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.Core.Reflection.Extensions;
+namespace Shared.Core.Reflection.Extensions;
public static class TypeExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Core/Reflection/ReflectionUtilities.cs b/src/Shared/Core/Reflection/ReflectionUtilities.cs
similarity index 99%
rename from src/Vertical.Slice.Template.Shared/Core/Reflection/ReflectionUtilities.cs
rename to src/Shared/Core/Reflection/ReflectionUtilities.cs
index bee6d31..c709a7b 100644
--- a/src/Vertical.Slice.Template.Shared/Core/Reflection/ReflectionUtilities.cs
+++ b/src/Shared/Core/Reflection/ReflectionUtilities.cs
@@ -2,7 +2,7 @@
using System.Reflection;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
-namespace Vertical.Slice.Template.Shared.Core.Reflection;
+namespace Shared.Core.Reflection;
public static class ReflectionUtilities
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/Converters/AggregateIdValueConverter.cs b/src/Shared/EF/Converters/AggregateIdValueConverter.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/EF/Converters/AggregateIdValueConverter.cs
rename to src/Shared/EF/Converters/AggregateIdValueConverter.cs
index 371494f..b323758 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Converters/AggregateIdValueConverter.cs
+++ b/src/Shared/EF/Converters/AggregateIdValueConverter.cs
@@ -1,8 +1,8 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Vertical.Slice.Template.Shared.Core.Domain;
+using Shared.Core.Domain;
-namespace Vertical.Slice.Template.Shared.EF.Converters;
+namespace Shared.EF.Converters;
// https://stackoverflow.com/questions/708952/how-to-instantiate-an-object-with-a-private-constructor-in-c
public class AggregateIdValueConverter : ValueConverter
diff --git a/src/Vertical.Slice.Template.Shared/EF/Converters/EntityIdValurConverter.cs b/src/Shared/EF/Converters/EntityIdValurConverter.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/EF/Converters/EntityIdValurConverter.cs
rename to src/Shared/EF/Converters/EntityIdValurConverter.cs
index d61b154..5e90b5c 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Converters/EntityIdValurConverter.cs
+++ b/src/Shared/EF/Converters/EntityIdValurConverter.cs
@@ -1,8 +1,8 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Vertical.Slice.Template.Shared.Core.Domain;
+using Shared.Core.Domain;
-namespace Vertical.Slice.Template.Shared.EF.Converters;
+namespace Shared.EF.Converters;
// https://stackoverflow.com/questions/708952/how-to-instantiate-an-object-with-a-private-constructor-in-c
public class EntityIdValurConverter : ValueConverter
diff --git a/src/Vertical.Slice.Template.Shared/EF/DbContextDesignFactoryBase.cs b/src/Shared/EF/DbContextDesignFactoryBase.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/EF/DbContextDesignFactoryBase.cs
rename to src/Shared/EF/DbContextDesignFactoryBase.cs
index 1108b19..415004e 100644
--- a/src/Vertical.Slice.Template.Shared/EF/DbContextDesignFactoryBase.cs
+++ b/src/Shared/EF/DbContextDesignFactoryBase.cs
@@ -3,7 +3,7 @@
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Extensions.Configuration;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
public abstract class DbContextDesignFactoryBase : IDesignTimeDbContextFactory
where TDbContext : DbContext
diff --git a/src/Vertical.Slice.Template.Shared/EF/EfConstants.cs b/src/Shared/EF/EfConstants.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/EF/EfConstants.cs
rename to src/Shared/EF/EfConstants.cs
index 3d2bc0c..fc43054 100644
--- a/src/Vertical.Slice.Template.Shared/EF/EfConstants.cs
+++ b/src/Shared/EF/EfConstants.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
public static class EfConstants
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/EfDbContextBase.cs b/src/Shared/EF/EfDbContextBase.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/EF/EfDbContextBase.cs
rename to src/Shared/EF/EfDbContextBase.cs
index 79c129b..efa59b2 100644
--- a/src/Vertical.Slice.Template.Shared/EF/EfDbContextBase.cs
+++ b/src/Shared/EF/EfDbContextBase.cs
@@ -3,11 +3,11 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
+using Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Persistence.Ef;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
// https://learn.microsoft.com/en-us/ef/core/saving/transactions
// https://learn.microsoft.com/en-us/ef/core/saving/
diff --git a/src/Vertical.Slice.Template.Shared/EF/EfTxBehavior.cs b/src/Shared/EF/EfTxBehavior.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/EF/EfTxBehavior.cs
rename to src/Shared/EF/EfTxBehavior.cs
index 4585c4d..9ad4628 100644
--- a/src/Vertical.Slice.Template.Shared/EF/EfTxBehavior.cs
+++ b/src/Shared/EF/EfTxBehavior.cs
@@ -1,11 +1,11 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Persistence.Ef;
using JsonSerializer = System.Text.Json.JsonSerializer;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
// Ref: https://github.com/thangchung/clean-architecture-dotnet/blob/main/src/N8T.Infrastructure.EfCore/TxBehavior.cs
public class EfTxBehavior : IPipelineBehavior
diff --git a/src/Vertical.Slice.Template.Shared/EF/Extensions/DbContextExtensions.cs b/src/Shared/EF/Extensions/DbContextExtensions.cs
similarity index 94%
rename from src/Vertical.Slice.Template.Shared/EF/Extensions/DbContextExtensions.cs
rename to src/Shared/EF/Extensions/DbContextExtensions.cs
index 536a47d..f9e95c8 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Extensions/DbContextExtensions.cs
+++ b/src/Shared/EF/Extensions/DbContextExtensions.cs
@@ -2,7 +2,7 @@
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
-namespace Vertical.Slice.Template.Shared.EF.Extensions;
+namespace Shared.EF.Extensions;
public static class DbContextExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/Extensions/ServiceCollectionExtensions.cs b/src/Shared/EF/Extensions/ServiceCollectionExtensions.cs
similarity index 87%
rename from src/Vertical.Slice.Template.Shared/EF/Extensions/ServiceCollectionExtensions.cs
rename to src/Shared/EF/Extensions/ServiceCollectionExtensions.cs
index a7cdbf0..8eb6681 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Extensions/ServiceCollectionExtensions.cs
+++ b/src/Shared/EF/Extensions/ServiceCollectionExtensions.cs
@@ -1,13 +1,13 @@
using System.Reflection;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
-using Vertical.Slice.Template.Shared.EF.Interceptors;
+using Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Extensions;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.EF.Interceptors;
-namespace Vertical.Slice.Template.Shared.EF.Extensions;
+namespace Shared.EF.Extensions;
public static class ServiceCollectionExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/Interceptors/AuditInterceptor.cs b/src/Shared/EF/Interceptors/AuditInterceptor.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/EF/Interceptors/AuditInterceptor.cs
rename to src/Shared/EF/Interceptors/AuditInterceptor.cs
index 54ae73d..1c28c7f 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Interceptors/AuditInterceptor.cs
+++ b/src/Shared/EF/Interceptors/AuditInterceptor.cs
@@ -1,8 +1,8 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.EF.Interceptors;
+namespace Shared.EF.Interceptors;
// https://khalidabuhakmeh.com/entity-framework-core-5-interceptors
// https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/interceptors#savechanges-interception
diff --git a/src/Vertical.Slice.Template.Shared/EF/Interceptors/ConcurrencyInterceptor.cs b/src/Shared/EF/Interceptors/ConcurrencyInterceptor.cs
similarity index 86%
rename from src/Vertical.Slice.Template.Shared/EF/Interceptors/ConcurrencyInterceptor.cs
rename to src/Shared/EF/Interceptors/ConcurrencyInterceptor.cs
index de73007..cc2cdf8 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Interceptors/ConcurrencyInterceptor.cs
+++ b/src/Shared/EF/Interceptors/ConcurrencyInterceptor.cs
@@ -1,8 +1,8 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
+using Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain.Events;
-namespace Vertical.Slice.Template.Shared.EF.Interceptors;
+namespace Shared.EF.Interceptors;
// https://khalidabuhakmeh.com/entity-framework-core-5-interceptors
// https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/interceptors#savechanges-interception
diff --git a/src/Vertical.Slice.Template.Shared/EF/Interceptors/SoftDeleteInterceptor.cs b/src/Shared/EF/Interceptors/SoftDeleteInterceptor.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/EF/Interceptors/SoftDeleteInterceptor.cs
rename to src/Shared/EF/Interceptors/SoftDeleteInterceptor.cs
index 041b15a..2790919 100644
--- a/src/Vertical.Slice.Template.Shared/EF/Interceptors/SoftDeleteInterceptor.cs
+++ b/src/Shared/EF/Interceptors/SoftDeleteInterceptor.cs
@@ -1,8 +1,8 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
+using Shared.Abstractions.Core.Domain;
-namespace Vertical.Slice.Template.Shared.EF.Interceptors;
+namespace Shared.EF.Interceptors;
// https://khalidabuhakmeh.com/entity-framework-core-5-interceptors
// https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/interceptors#savechanges-interception
diff --git a/src/Vertical.Slice.Template.Shared/EF/NpgsqlConnectionFactory.cs b/src/Shared/EF/NpgsqlConnectionFactory.cs
similarity index 84%
rename from src/Vertical.Slice.Template.Shared/EF/NpgsqlConnectionFactory.cs
rename to src/Shared/EF/NpgsqlConnectionFactory.cs
index 5f32cca..8f7fdd1 100644
--- a/src/Vertical.Slice.Template.Shared/EF/NpgsqlConnectionFactory.cs
+++ b/src/Shared/EF/NpgsqlConnectionFactory.cs
@@ -1,10 +1,10 @@
using System.Data;
using System.Data.Common;
using Npgsql;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-using Vertical.Slice.Template.Shared.Core.Extensions;
+using Shared.Abstractions.Persistence.Ef;
+using Shared.Core.Extensions;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
public class NpgsqlConnectionFactory : IConnectionFactory
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/PostgresOptions.cs b/src/Shared/EF/PostgresOptions.cs
similarity index 81%
rename from src/Vertical.Slice.Template.Shared/EF/PostgresOptions.cs
rename to src/Shared/EF/PostgresOptions.cs
index dd59e58..aec3465 100644
--- a/src/Vertical.Slice.Template.Shared/EF/PostgresOptions.cs
+++ b/src/Shared/EF/PostgresOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
public class PostgresOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/EF/SqlKataExtensions.cs b/src/Shared/EF/SqlKataExtensions.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/EF/SqlKataExtensions.cs
rename to src/Shared/EF/SqlKataExtensions.cs
index 20772e5..d8ba093 100644
--- a/src/Vertical.Slice.Template.Shared/EF/SqlKataExtensions.cs
+++ b/src/Shared/EF/SqlKataExtensions.cs
@@ -4,7 +4,7 @@
using SqlKata;
using SqlKata.Compilers;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
// Ref: https://github.com/sqlkata/querybuilder
// Ref: https://github.com/fulviocanducci/Canducci.SqlKata.Dapper
diff --git a/src/Vertical.Slice.Template.Shared/EF/StronglyTypedIdValueConverterSelector.cs b/src/Shared/EF/StronglyTypedIdValueConverterSelector.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/EF/StronglyTypedIdValueConverterSelector.cs
rename to src/Shared/EF/StronglyTypedIdValueConverterSelector.cs
index 2cf586b..8800e1f 100644
--- a/src/Vertical.Slice.Template.Shared/EF/StronglyTypedIdValueConverterSelector.cs
+++ b/src/Shared/EF/StronglyTypedIdValueConverterSelector.cs
@@ -1,9 +1,9 @@
using System.Collections.Concurrent;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Vertical.Slice.Template.Shared.Core.Domain;
-using Vertical.Slice.Template.Shared.EF.Converters;
+using Shared.Core.Domain;
+using Shared.EF.Converters;
-namespace Vertical.Slice.Template.Shared.EF;
+namespace Shared.EF;
// Ref: https://andrewlock.net/series/using-strongly-typed-entity-ids-to-avoid-primitive-obsession/
// https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-4/
diff --git a/src/Vertical.Slice.Template.Shared/Logging/Extensions.cs b/src/Shared/Logging/Extensions.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Logging/Extensions.cs
rename to src/Shared/Logging/Extensions.cs
index 077b238..153abfb 100644
--- a/src/Vertical.Slice.Template.Shared/Logging/Extensions.cs
+++ b/src/Shared/Logging/Extensions.cs
@@ -6,10 +6,9 @@
using Serilog.Formatting.Elasticsearch;
using Serilog.Sinks.Elasticsearch;
using Serilog.Sinks.Grafana.Loki;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Web.Extensions;
+using Shared.Core.Extensions;
-namespace Vertical.Slice.Template.Shared.Logging;
+namespace Shared.Logging;
public static class RegistrationExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Logging/LoggingBehavior.cs b/src/Shared/Logging/LoggingBehavior.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Logging/LoggingBehavior.cs
rename to src/Shared/Logging/LoggingBehavior.cs
index c422f20..3e3f243 100644
--- a/src/Vertical.Slice.Template.Shared/Logging/LoggingBehavior.cs
+++ b/src/Shared/Logging/LoggingBehavior.cs
@@ -2,7 +2,7 @@
using MediatR;
using Microsoft.Extensions.Logging;
-namespace Vertical.Slice.Template.Shared.Logging;
+namespace Shared.Logging;
public class LoggingBehavior : IPipelineBehavior
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Logging/SerilogOptions.cs b/src/Shared/Logging/SerilogOptions.cs
similarity index 91%
rename from src/Vertical.Slice.Template.Shared/Logging/SerilogOptions.cs
rename to src/Shared/Logging/SerilogOptions.cs
index 5fd6090..19aebce 100644
--- a/src/Vertical.Slice.Template.Shared/Logging/SerilogOptions.cs
+++ b/src/Shared/Logging/SerilogOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Logging;
+namespace Shared.Logging;
internal sealed class SerilogOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/CorrelationIdDelegatingHandler.cs b/src/Shared/Resiliency/CorrelationIdDelegatingHandler.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/Resiliency/CorrelationIdDelegatingHandler.cs
rename to src/Shared/Resiliency/CorrelationIdDelegatingHandler.cs
index da868ca..c40de6a 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/CorrelationIdDelegatingHandler.cs
+++ b/src/Shared/Resiliency/CorrelationIdDelegatingHandler.cs
@@ -2,7 +2,7 @@
using CorrelationId.Abstractions;
using Microsoft.Extensions.Options;
-namespace Vertical.Slice.Template.Shared.Resiliency;
+namespace Shared.Resiliency;
public class CorrelationIdDelegatingHandler : DelegatingHandler
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/DefaultHttpClientHandler.cs b/src/Shared/Resiliency/DefaultHttpClientHandler.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Resiliency/DefaultHttpClientHandler.cs
rename to src/Shared/Resiliency/DefaultHttpClientHandler.cs
index b1298a5..b07c114 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/DefaultHttpClientHandler.cs
+++ b/src/Shared/Resiliency/DefaultHttpClientHandler.cs
@@ -1,6 +1,6 @@
using System.Net;
-namespace Vertical.Slice.Template.Shared.Resiliency;
+namespace Shared.Resiliency;
public class DefaultHttpClientHandler : HttpClientHandler
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs b/src/Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs
rename to src/Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs
index 7bd2e99..0421150 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs
+++ b/src/Shared/Resiliency/Extensions/HttpClientBuilderExtensions.cs
@@ -3,9 +3,9 @@
using Polly;
using Polly.CircuitBreaker;
using Polly.Timeout;
-using Vertical.Slice.Template.Shared.Resiliency.Options;
+using Shared.Resiliency.Options;
-namespace Vertical.Slice.Template.Shared.Resiliency.Extensions;
+namespace Shared.Resiliency.Extensions;
// https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory
public static class HttpClientBuilderExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/PollyContextExtensions.cs b/src/Shared/Resiliency/Extensions/PollyContextExtensions.cs
similarity index 91%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Extensions/PollyContextExtensions.cs
rename to src/Shared/Resiliency/Extensions/PollyContextExtensions.cs
index 66d0663..cc0cae2 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/PollyContextExtensions.cs
+++ b/src/Shared/Resiliency/Extensions/PollyContextExtensions.cs
@@ -1,7 +1,7 @@
using Microsoft.Extensions.Logging;
using Polly;
-namespace Vertical.Slice.Template.Shared.Resiliency.Extensions;
+namespace Shared.Resiliency.Extensions;
// https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory#configuring-httpclientfactory-policies-to-use-an-iloggert-from-the-call-site
public static class PollyContextExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs b/src/Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs
rename to src/Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs
index 8867c36..479ade3 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs
+++ b/src/Shared/Resiliency/Extensions/ServiceCollectionsExtensions.cs
@@ -1,15 +1,13 @@
-using CorrelationId;
-using CorrelationId.Abstractions;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Polly;
using Polly.CircuitBreaker;
using Polly.Timeout;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
-using Vertical.Slice.Template.Shared.Resiliency.Options;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.Resiliency.Options;
-namespace Vertical.Slice.Template.Shared.Resiliency.Extensions;
+namespace Shared.Resiliency.Extensions;
public static class ServiceCollectionsExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/BulkheadPolicyOptions.cs b/src/Shared/Resiliency/Options/BulkheadPolicyOptions.cs
similarity index 70%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/BulkheadPolicyOptions.cs
rename to src/Shared/Resiliency/Options/BulkheadPolicyOptions.cs
index 7045b7b..e5f3d3d 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/BulkheadPolicyOptions.cs
+++ b/src/Shared/Resiliency/Options/BulkheadPolicyOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class BulkheadPolicyOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs b/src/Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs
similarity index 91%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs
rename to src/Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs
index f68c917..a5a4001 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs
+++ b/src/Shared/Resiliency/Options/CircuitBreakerPolicyOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class CircuitBreakerPolicyOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/HttpClientOptions.cs b/src/Shared/Resiliency/Options/HttpClientOptions.cs
similarity index 71%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/HttpClientOptions.cs
rename to src/Shared/Resiliency/Options/HttpClientOptions.cs
index fa81b5c..6ab7d9d 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/HttpClientOptions.cs
+++ b/src/Shared/Resiliency/Options/HttpClientOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class HttpClientOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/PolicyOptions.cs b/src/Shared/Resiliency/Options/PolicyOptions.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/PolicyOptions.cs
rename to src/Shared/Resiliency/Options/PolicyOptions.cs
index e511433..2380b68 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/PolicyOptions.cs
+++ b/src/Shared/Resiliency/Options/PolicyOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class PolicyOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/RetryPolicyOptions.cs b/src/Shared/Resiliency/Options/RetryPolicyOptions.cs
similarity index 67%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/RetryPolicyOptions.cs
rename to src/Shared/Resiliency/Options/RetryPolicyOptions.cs
index efc1a3b..af24785 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/RetryPolicyOptions.cs
+++ b/src/Shared/Resiliency/Options/RetryPolicyOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class RetryPolicyOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/Options/TimeoutPolicyOptions.cs b/src/Shared/Resiliency/Options/TimeoutPolicyOptions.cs
similarity index 59%
rename from src/Vertical.Slice.Template.Shared/Resiliency/Options/TimeoutPolicyOptions.cs
rename to src/Shared/Resiliency/Options/TimeoutPolicyOptions.cs
index 6cc7ca2..b5e9c54 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/Options/TimeoutPolicyOptions.cs
+++ b/src/Shared/Resiliency/Options/TimeoutPolicyOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency.Options;
+namespace Shared.Resiliency.Options;
public class TimeoutPolicyOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Resiliency/PolicyNames.cs b/src/Shared/Resiliency/PolicyNames.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Resiliency/PolicyNames.cs
rename to src/Shared/Resiliency/PolicyNames.cs
index 75eae00..6f32554 100644
--- a/src/Vertical.Slice.Template.Shared/Resiliency/PolicyNames.cs
+++ b/src/Shared/Resiliency/PolicyNames.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Resiliency;
+namespace Shared.Resiliency;
public static class PolicyNames
{
diff --git a/src/Vertical.Slice.Template.Shared/Vertical.Slice.Template.Shared.csproj b/src/Shared/Shared.csproj
similarity index 100%
rename from src/Vertical.Slice.Template.Shared/Vertical.Slice.Template.Shared.csproj
rename to src/Shared/Shared.csproj
diff --git a/src/Vertical.Slice.Template.Shared/Swagger/ConfigureSwaggerOptions.cs b/src/Shared/Swagger/ConfigureSwaggerOptions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Swagger/ConfigureSwaggerOptions.cs
rename to src/Shared/Swagger/ConfigureSwaggerOptions.cs
index 0fd25e9..78f7621 100644
--- a/src/Vertical.Slice.Template.Shared/Swagger/ConfigureSwaggerOptions.cs
+++ b/src/Shared/Swagger/ConfigureSwaggerOptions.cs
@@ -5,7 +5,7 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
-namespace Vertical.Slice.Template.Shared.Swagger;
+namespace Shared.Swagger;
///
/// Configures the Swagger generation options.
diff --git a/src/Vertical.Slice.Template.Shared/Swagger/Extensions.cs b/src/Shared/Swagger/Extensions.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Swagger/Extensions.cs
rename to src/Shared/Swagger/Extensions.cs
index b745afc..dbd4606 100644
--- a/src/Vertical.Slice.Template.Shared/Swagger/Extensions.cs
+++ b/src/Shared/Swagger/Extensions.cs
@@ -2,7 +2,7 @@
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerGen;
-namespace Vertical.Slice.Template.Shared.Swagger;
+namespace Shared.Swagger;
public static class Extensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Swagger/SwaggerDefaultValues.cs b/src/Shared/Swagger/SwaggerDefaultValues.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Swagger/SwaggerDefaultValues.cs
rename to src/Shared/Swagger/SwaggerDefaultValues.cs
index 0ef3ee7..0318727 100644
--- a/src/Vertical.Slice.Template.Shared/Swagger/SwaggerDefaultValues.cs
+++ b/src/Shared/Swagger/SwaggerDefaultValues.cs
@@ -4,7 +4,7 @@
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
-namespace Vertical.Slice.Template.Shared.Swagger;
+namespace Shared.Swagger;
///
/// Represents the OpenAPI/Swashbuckle operation filter used to document information provided, but not used.
diff --git a/src/Vertical.Slice.Template.Shared/Validation/Extensions/RegistrationExtensions.cs b/src/Shared/Validation/Extensions/RegistrationExtensions.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/Validation/Extensions/RegistrationExtensions.cs
rename to src/Shared/Validation/Extensions/RegistrationExtensions.cs
index e19ed65..9894131 100644
--- a/src/Vertical.Slice.Template.Shared/Validation/Extensions/RegistrationExtensions.cs
+++ b/src/Shared/Validation/Extensions/RegistrationExtensions.cs
@@ -2,7 +2,7 @@
using FluentValidation;
using Scrutor;
-namespace Vertical.Slice.Template.Shared.Validation.Extensions;
+namespace Shared.Validation.Extensions;
public static class RegistrationExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Validation/Extensions/ValidatorExtension.cs b/src/Shared/Validation/Extensions/ValidatorExtension.cs
similarity index 88%
rename from src/Vertical.Slice.Template.Shared/Validation/Extensions/ValidatorExtension.cs
rename to src/Shared/Validation/Extensions/ValidatorExtension.cs
index 44b774c..d8f7af9 100644
--- a/src/Vertical.Slice.Template.Shared/Validation/Extensions/ValidatorExtension.cs
+++ b/src/Shared/Validation/Extensions/ValidatorExtension.cs
@@ -1,8 +1,8 @@
using FluentValidation;
using FluentValidation.Results;
-using ValidationException = Vertical.Slice.Template.Shared.Core.Exceptions.ValidationException;
+using ValidationException = Shared.Core.Exceptions.ValidationException;
-namespace Vertical.Slice.Template.Shared.Validation.Extensions;
+namespace Shared.Validation.Extensions;
public static class ValidatorExtension
{
diff --git a/src/Vertical.Slice.Template.Shared/Validation/RequestValidationBehavior.cs b/src/Shared/Validation/RequestValidationBehavior.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Validation/RequestValidationBehavior.cs
rename to src/Shared/Validation/RequestValidationBehavior.cs
index 5200d00..1bdd8e5 100644
--- a/src/Vertical.Slice.Template.Shared/Validation/RequestValidationBehavior.cs
+++ b/src/Shared/Validation/RequestValidationBehavior.cs
@@ -2,9 +2,9 @@
using FluentValidation;
using MediatR;
using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Validation.Extensions;
+using Shared.Validation.Extensions;
-namespace Vertical.Slice.Template.Shared.Validation;
+namespace Shared.Validation;
public class RequestValidationBehavior : IPipelineBehavior
where TRequest : IRequest
diff --git a/src/Vertical.Slice.Template.Shared/Validation/ValidationError.cs b/src/Shared/Validation/ValidationError.cs
similarity index 82%
rename from src/Vertical.Slice.Template.Shared/Validation/ValidationError.cs
rename to src/Shared/Validation/ValidationError.cs
index d33e561..b2ebbe8 100644
--- a/src/Vertical.Slice.Template.Shared/Validation/ValidationError.cs
+++ b/src/Shared/Validation/ValidationError.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Validation;
+namespace Shared.Validation;
public class ValidationError
{
diff --git a/src/Vertical.Slice.Template.Shared/Validation/ValidationResultModel.cs b/src/Shared/Validation/ValidationResultModel.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/Validation/ValidationResultModel.cs
rename to src/Shared/Validation/ValidationResultModel.cs
index def377f..dccb4ba 100644
--- a/src/Vertical.Slice.Template.Shared/Validation/ValidationResultModel.cs
+++ b/src/Shared/Validation/ValidationResultModel.cs
@@ -3,7 +3,7 @@
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
-namespace Vertical.Slice.Template.Shared.Validation;
+namespace Shared.Validation;
public class ValidationResultModel
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/CorsOptions.cs b/src/Shared/Web/CorsOptions.cs
similarity index 65%
rename from src/Vertical.Slice.Template.Shared/Web/CorsOptions.cs
rename to src/Shared/Web/CorsOptions.cs
index c2c5659..a53b72a 100644
--- a/src/Vertical.Slice.Template.Shared/Web/CorsOptions.cs
+++ b/src/Shared/Web/CorsOptions.cs
@@ -1,4 +1,4 @@
-namespace Vertical.Slice.Template.Shared.Web;
+namespace Shared.Web;
public class CorsOptions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/CompressionExtensions.cs b/src/Shared/Web/Extensions/CompressionExtensions.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/CompressionExtensions.cs
rename to src/Shared/Web/Extensions/CompressionExtensions.cs
index 0ccd002..32a5e0e 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/CompressionExtensions.cs
+++ b/src/Shared/Web/Extensions/CompressionExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.ResponseCompression;
-namespace Vertical.Slice.Template.Shared.Web.Extensions;
+namespace Shared.Web.Extensions;
public static partial class CompressionExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/CorsExtensions.cs b/src/Shared/Web/Extensions/CorsExtensions.cs
similarity index 87%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/CorsExtensions.cs
rename to src/Shared/Web/Extensions/CorsExtensions.cs
index 53f90f6..0d7832f 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/CorsExtensions.cs
+++ b/src/Shared/Web/Extensions/CorsExtensions.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
-namespace Vertical.Slice.Template.Shared.Web.Extensions;
+namespace Shared.Web.Extensions;
// https://learn.microsoft.com/en-us/aspnet/core/security/cors
public static class Extensions
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/HeaderDictionaryExtensions.cs b/src/Shared/Web/Extensions/HeaderDictionaryExtensions.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/HeaderDictionaryExtensions.cs
rename to src/Shared/Web/Extensions/HeaderDictionaryExtensions.cs
index 9801858..c10914e 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/HeaderDictionaryExtensions.cs
+++ b/src/Shared/Web/Extensions/HeaderDictionaryExtensions.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Web.Extensions;
+namespace Shared.Web.Extensions;
// https://khalidabuhakmeh.com/read-and-convert-querycollection-values-in-aspnet
public static class HeaderDictionaryExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/HttpResponseMessageExtensions.cs b/src/Shared/Web/Extensions/HttpResponseMessageExtensions.cs
similarity index 89%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/HttpResponseMessageExtensions.cs
rename to src/Shared/Web/Extensions/HttpResponseMessageExtensions.cs
index 1e45cbc..907ab95 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/HttpResponseMessageExtensions.cs
+++ b/src/Shared/Web/Extensions/HttpResponseMessageExtensions.cs
@@ -1,6 +1,6 @@
-using Vertical.Slice.Template.Shared.Core.Exceptions;
+using Shared.Core.Exceptions;
-namespace Vertical.Slice.Template.Shared.Web.Extensions;
+namespace Shared.Web.Extensions;
public static class HttpResponseMessageExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/QueryCollectionExtensions.cs b/src/Shared/Web/Extensions/QueryCollectionExtensions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/QueryCollectionExtensions.cs
rename to src/Shared/Web/Extensions/QueryCollectionExtensions.cs
index e6c0708..9fc7e14 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/QueryCollectionExtensions.cs
+++ b/src/Shared/Web/Extensions/QueryCollectionExtensions.cs
@@ -3,7 +3,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
-namespace Vertical.Slice.Template.Shared.Web.Extensions;
+namespace Shared.Web.Extensions;
// https://khalidabuhakmeh.com/read-and-convert-querycollection-values-in-aspnet
public static class QueryCollectionExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs b/src/Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs
rename to src/Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs
index 17d2d5a..d7684a9 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs
+++ b/src/Shared/Web/Extensions/WebApplicationBuilderExtensions/WebApplicationBuilderExtensions.Versioning.cs
@@ -1,7 +1,7 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Builder;
-namespace Vertical.Slice.Template.Shared.Web.Extensions.WebApplicationBuilderExtensions;
+namespace Shared.Web.Extensions.WebApplicationBuilderExtensions;
public static partial class WebApplicationBuilderExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs b/src/Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs
rename to src/Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs
index 496aec0..13bd3f9 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs
+++ b/src/Shared/Web/Minimal/Extensions/EndpointConventionBuilderExtensions.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
-namespace Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+namespace Shared.Web.Minimal.Extensions;
public static class EndpointConventionBuilderExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs b/src/Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs
similarity index 98%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs
rename to src/Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs
index 2387a78..90f45cb 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs
+++ b/src/Shared/Web/Minimal/Extensions/EndpointRouteBuilderExtensions.cs
@@ -4,9 +4,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Routing;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
+using Shared.Abstractions.Web;
-namespace Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+namespace Shared.Web.Minimal.Extensions;
public static class EndpointRouteBuilderExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs b/src/Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs
similarity index 95%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs
rename to src/Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs
index a0466c5..5cc0cf3 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs
+++ b/src/Shared/Web/Minimal/Extensions/MinimalApiExtensions.cs
@@ -3,10 +3,10 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Scrutor;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Core.Reflection;
+using Shared.Abstractions.Web;
+using Shared.Core.Reflection;
-namespace Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+namespace Shared.Web.Minimal.Extensions;
public static class MinimalApiExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/ModuleExtensions.cs b/src/Shared/Web/Minimal/Extensions/ModuleExtensions.cs
similarity index 93%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/ModuleExtensions.cs
rename to src/Shared/Web/Minimal/Extensions/ModuleExtensions.cs
index 7c1b11a..2f9ca30 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/ModuleExtensions.cs
+++ b/src/Shared/Web/Minimal/Extensions/ModuleExtensions.cs
@@ -1,11 +1,11 @@
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Core.Reflection;
-using Vertical.Slice.Template.Shared.Core.Reflection.Extensions;
+using Shared.Abstractions.Web;
+using Shared.Core.Reflection;
+using Shared.Core.Reflection.Extensions;
-namespace Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+namespace Shared.Web.Minimal.Extensions;
public static class ModuleExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs b/src/Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs
similarity index 91%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs
rename to src/Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs
index a937e5b..07c8071 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs
+++ b/src/Shared/Web/Minimal/Extensions/TypedResultsExtensions.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc;
-using Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
+using Shared.Web.ProblemDetail.HttpResults;
-namespace Vertical.Slice.Template.Shared.Web.Minimal.Extensions;
+namespace Shared.Web.Minimal.Extensions;
public static class TypedResultsExtensions
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/HttpCommand.cs b/src/Shared/Web/Minimal/HttpCommand.cs
similarity index 71%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/HttpCommand.cs
rename to src/Shared/Web/Minimal/HttpCommand.cs
index 778beb3..ea1a027 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/HttpCommand.cs
+++ b/src/Shared/Web/Minimal/HttpCommand.cs
@@ -1,9 +1,9 @@
using AutoMapper;
using MediatR;
using Microsoft.AspNetCore.Http;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
+using Shared.Abstractions.Web;
-namespace Vertical.Slice.Template.Shared.Web.Minimal;
+namespace Shared.Web.Minimal;
public record HttpCommand(
TRequest Request,
diff --git a/src/Vertical.Slice.Template.Shared/Web/Minimal/HttpQuery.cs b/src/Shared/Web/Minimal/HttpQuery.cs
similarity index 67%
rename from src/Vertical.Slice.Template.Shared/Web/Minimal/HttpQuery.cs
rename to src/Shared/Web/Minimal/HttpQuery.cs
index 2a22e89..fcc5f58 100644
--- a/src/Vertical.Slice.Template.Shared/Web/Minimal/HttpQuery.cs
+++ b/src/Shared/Web/Minimal/HttpQuery.cs
@@ -1,9 +1,9 @@
using AutoMapper;
using MediatR;
using Microsoft.AspNetCore.Http;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
+using Shared.Abstractions.Web;
-namespace Vertical.Slice.Template.Shared.Web.Minimal;
+namespace Shared.Web.Minimal;
public record HttpQuery(
HttpContext HttpContext,
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs b/src/Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs
similarity index 84%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs
rename to src/Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs
index cbb0f07..e726847 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs
+++ b/src/Shared/Web/ProblemDetail/DefaultProblemDetailMapper.cs
@@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Http;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
+using Shared.Abstractions.Web;
+using Shared.Core.Exceptions;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail;
+namespace Shared.Web.ProblemDetail;
internal sealed class DefaultProblemDetailMapper : IProblemDetailMapper
{
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs b/src/Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs
rename to src/Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs
index 2c1dffc..c5ef821 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs
+++ b/src/Shared/Web/ProblemDetail/HttpResults/InternalHttpProblemResult.cs
@@ -5,7 +5,7 @@
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.AspNetCore.Mvc;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
+namespace Shared.Web.ProblemDetail.HttpResults;
public class InternalHttpProblemResult
: IResult,
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs b/src/Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs
rename to src/Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs
index 1d7bdbc..69b003c 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs
+++ b/src/Shared/Web/ProblemDetail/HttpResults/NotFoundHttpProblemResult.cs
@@ -5,7 +5,7 @@
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.AspNetCore.Mvc;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
+namespace Shared.Web.ProblemDetail.HttpResults;
public class NotFoundHttpProblemResult
: IResult,
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs b/src/Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs
similarity index 96%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs
rename to src/Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs
index 16eaaef..fe50091 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs
+++ b/src/Shared/Web/ProblemDetail/HttpResults/UnAuthorizedHttpProblemResult.cs
@@ -5,7 +5,7 @@
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.AspNetCore.Mvc;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail.HttpResults;
+namespace Shared.Web.ProblemDetail.HttpResults;
public class UnAuthorizedHttpProblemResult
: IResult,
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs b/src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs
similarity index 85%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs
rename to src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs
index 9b9a070..80d738d 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs
+++ b/src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareExtensions.cs
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Builder;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail.Middlewares.CaptureExceptionMiddleware;
+namespace Shared.Web.ProblemDetail.Middlewares.CaptureExceptionMiddleware;
//https://github.com/dotnet/aspnetcore/pull/47760
public static class CaptureExceptionMiddlewareExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs b/src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs
similarity index 92%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs
rename to src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs
index f154a69..bcf269e 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs
+++ b/src/Shared/Web/ProblemDetail/Middlewares/CaptureExceptionMiddleware/CaptureExceptionMiddlewareImp.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail.Middlewares.CaptureExceptionMiddleware;
+namespace Shared.Web.ProblemDetail.Middlewares.CaptureExceptionMiddleware;
// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write
public class CaptureExceptionMiddlewareImp
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsService.cs b/src/Shared/Web/ProblemDetail/ProblemDetailsService.cs
similarity index 97%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsService.cs
rename to src/Shared/Web/ProblemDetail/ProblemDetailsService.cs
index e68fbf7..2b2ca6f 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsService.cs
+++ b/src/Shared/Web/ProblemDetail/ProblemDetailsService.cs
@@ -1,9 +1,9 @@
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
+using Shared.Abstractions.Web;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail;
+namespace Shared.Web.ProblemDetail;
// https://www.strathweb.com/2022/08/problem-details-responses-everywhere-with-asp-net-core-and-net-7/
public class ProblemDetailsService : IProblemDetailsService
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsWriter.cs b/src/Shared/Web/ProblemDetail/ProblemDetailsWriter.cs
similarity index 94%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsWriter.cs
rename to src/Shared/Web/ProblemDetail/ProblemDetailsWriter.cs
index 2f320c4..4973de9 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/ProblemDetailsWriter.cs
+++ b/src/Shared/Web/ProblemDetail/ProblemDetailsWriter.cs
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail;
+namespace Shared.Web.ProblemDetail;
// https://www.strathweb.com/2022/08/problem-details-responses-everywhere-with-asp-net-core-and-net-7/#toc_3
public class ProblemDetailsWriter : IProblemDetailsWriter
diff --git a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/RegistrationExtensions.cs b/src/Shared/Web/ProblemDetail/RegistrationExtensions.cs
similarity index 83%
rename from src/Vertical.Slice.Template.Shared/Web/ProblemDetail/RegistrationExtensions.cs
rename to src/Shared/Web/ProblemDetail/RegistrationExtensions.cs
index d8d4804..2551e57 100644
--- a/src/Vertical.Slice.Template.Shared/Web/ProblemDetail/RegistrationExtensions.cs
+++ b/src/Shared/Web/ProblemDetail/RegistrationExtensions.cs
@@ -1,11 +1,10 @@
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Scrutor;
-using Vertical.Slice.Template.Shared.Abstractions.Web;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
-using Vertical.Slice.Template.Shared.Core.Reflection;
+using Shared.Abstractions.Web;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
-namespace Vertical.Slice.Template.Shared.Web.ProblemDetail;
+namespace Shared.Web.ProblemDetail;
// https://www.strathweb.com/2022/08/problem-details-responses-everywhere-with-asp-net-core-and-net-7/
public static class RegistrationExtensions
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IPageQuery.cs b/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IPageQuery.cs
deleted file mode 100644
index 8b58e79..0000000
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/CQRS/IPageQuery.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Paging;
-
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.CQRS;
-
-public interface IPageQuery : IPageRequest, IQuery
- where TResponse : class { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs b/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs
deleted file mode 100644
index f7ed4c6..0000000
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/Events/IHaveNotificationEvent.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-
-public interface IHaveNotificationEvent { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregate.cs b/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregate.cs
deleted file mode 100644
index e818980..0000000
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveAggregate.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using Vertical.Slice.Template.Shared.Abstractions.Core.Domain.Events;
-
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-
-public interface IHaveAggregate : IHaveDomainEvents, IHaveAggregateVersion { }
diff --git a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs b/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs
deleted file mode 100644
index 3d3fc7b..0000000
--- a/src/Vertical.Slice.Template.Shared/Abstractions/Core/Domain/IHaveSoftDelete.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace Vertical.Slice.Template.Shared.Abstractions.Core.Domain;
-
-public interface IHaveSoftDelete { }
diff --git a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs b/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs
deleted file mode 100644
index 2a13a3b..0000000
--- a/src/Vertical.Slice.Template.Shared/Core/Extensions/ServiceCollectionsExtensions/ServiceCollectionExtensions.Options.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using Microsoft.Extensions.Options;
-
-namespace Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
-
-public static partial class ServiceCollectionExtensions
-{
- public static IServiceCollection AddConfigurationOptions(this IServiceCollection services)
- where T : class
- {
- return services.AddConfigurationOptions(typeof(T).Name);
- }
-
- public static IServiceCollection AddConfigurationOptions(this IServiceCollection services, string key)
- where T : class
- {
- services.AddOptions().BindConfiguration(key);
-
- return services.AddSingleton(x => x.GetRequiredService>().Value);
- }
-
- public static IServiceCollection AddValidatedOptions(this IServiceCollection services)
- where T : class
- {
- return AddValidatedOptions(services, typeof(T).Name, RequiredConfigurationValidator.Validate);
- }
-
- public static IServiceCollection AddValidatedOptions(this IServiceCollection services, string key)
- where T : class
- {
- return AddValidatedOptions(services, key, RequiredConfigurationValidator.Validate);
- }
-
- public static IServiceCollection AddValidatedOptions(
- this IServiceCollection services,
- string key,
- Func validator
- )
- where T : class
- {
- // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options
- // https://thecodeblogger.com/2021/04/21/options-pattern-in-net-ioptions-ioptionssnapshot-ioptionsmonitor/
- // https://code-maze.com/aspnet-configuration-options/
- // https://code-maze.com/aspnet-configuration-options-validation/
- // https://dotnetdocs.ir/Post/42/difference-between-ioptions-ioptionssnapshot-and-ioptionsmonitor
- // https://andrewlock.net/adding-validation-to-strongly-typed-configuration-objects-in-dotnet-6/
- services.AddOptions().BindConfiguration(key).Validate(validator);
-
- // IOptions itself registered as singleton
- return services.AddSingleton(x => x.GetRequiredService>().Value);
- }
-}
-
-public static class RequiredConfigurationValidator
-{
- public static bool Validate(T arg)
- where T : class
- {
- var requiredProperties = typeof(T)
- .GetProperties(BindingFlags.Public | BindingFlags.Instance)
- .Where(x => Attribute.IsDefined(x, typeof(RequiredMemberAttribute)));
-
- foreach (var requiredProperty in requiredProperties)
- {
- var propertyValue = requiredProperty.GetValue(arg);
- if (propertyValue is null)
- {
- throw new System.Exception($"Required property '{requiredProperty.Name}' was null");
- }
- }
-
- return true;
- }
-}
diff --git a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs b/src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs
deleted file mode 100644
index 753b52c..0000000
--- a/src/Vertical.Slice.Template/Shared/Clients/Catalogs/CatalogsApiClientOptions.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using Vertical.Slice.Template.Shared.Resiliency.Options;
-
-namespace Vertical.Slice.Template.Shared.Clients.Catalogs;
-
-public class CatalogsApiClientOptions : HttpClientOptions { }
diff --git a/src/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs b/src/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs
deleted file mode 100644
index c5a5462..0000000
--- a/src/Vertical.Slice.Template/Shared/Data/CatalogsDbContextDesignFactory.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Vertical.Slice.Template.Shared.EF;
-
-namespace Vertical.Slice.Template.Shared.Data;
-
-public class CatalogsDbContextDesignFactory : DbContextDesignFactoryBase
-{
- public CatalogsDbContextDesignFactory()
- : base($"{nameof(PostgresOptions)}:{nameof(PostgresOptions.ConnectionString)}") { }
-}
diff --git a/src/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs b/src/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs
deleted file mode 100644
index 9684c64..0000000
--- a/src/Vertical.Slice.Template/Shared/Data/CatalogsMigrationExecutor.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-
-namespace Vertical.Slice.Template.Shared.Data;
-
-public class CatalogsMigrationExecutor : IMigrationExecutor
-{
- private readonly CatalogsDbContext _catalogsDbContext;
- private readonly ILogger _logger;
-
- public CatalogsMigrationExecutor(CatalogsDbContext catalogsDbContext, ILogger logger)
- {
- _catalogsDbContext = catalogsDbContext;
- _logger = logger;
- }
-
- public async Task ExecuteAsync(CancellationToken cancellationToken)
- {
- _logger.LogInformation("Migration worker started");
-
- _logger.LogInformation("Updating catalog database...");
-
- await _catalogsDbContext.Database.MigrateAsync(cancellationToken: cancellationToken);
-
- _logger.LogInformation("Catalog database Updated");
- }
-}
diff --git a/src/Vertical.Slice.Template/Shared/Data/GenericRepository.cs b/src/Vertical.Slice.Template/Shared/Data/GenericRepository.cs
deleted file mode 100644
index 66f3065..0000000
--- a/src/Vertical.Slice.Template/Shared/Data/GenericRepository.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Vertical.Slice.Template.Shared.Core.Ef;
-
-namespace Vertical.Slice.Template.Shared.Data;
-
-public class GenericRepository : EfRepository
- where T : class
-{
- public GenericRepository(CatalogsDbContext dbContext)
- : base(dbContext) { }
-}
diff --git a/src/Vertical.Slice.Template/Shared/Workers/MigrationWorker.cs b/src/Vertical.Slice.Template/Shared/Workers/MigrationWorker.cs
deleted file mode 100644
index b75cc9c..0000000
--- a/src/Vertical.Slice.Template/Shared/Workers/MigrationWorker.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-
-namespace Vertical.Slice.Template.Shared.Workers;
-
-// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
-// Hint: we can't guarantee execution order of our migration before our test so we should apply it manually in tests
-public class MigrationWorker : BackgroundService
-{
- private readonly IServiceScopeFactory _serviceScopeFactory;
- private readonly ILogger _logger;
- private readonly IWebHostEnvironment _webHostEnvironment;
-
- public MigrationWorker(
- IServiceScopeFactory serviceScopeFactory,
- ILogger logger,
- IWebHostEnvironment webHostEnvironment
- )
- {
- _serviceScopeFactory = serviceScopeFactory;
- _logger = logger;
- _webHostEnvironment = webHostEnvironment;
- }
-
- protected override async Task ExecuteAsync(CancellationToken stoppingToken)
- {
- if (!_webHostEnvironment.IsEnvironment("test"))
- {
- // https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
- // https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
- using var serviceScope = _serviceScopeFactory.CreateScope();
- var migrations = serviceScope.ServiceProvider.GetServices();
-
- foreach (var migration in migrations)
- {
- _logger.LogInformation("Migration '{Migration}' started...", migrations.GetType().Name);
- await migration.ExecuteAsync(stoppingToken);
- _logger.LogInformation("Migration '{Migration}' ended...", migration.GetType().Name);
- }
- }
- }
-
- public override Task StopAsync(CancellationToken cancellationToken)
- {
- if (!_webHostEnvironment.IsEnvironment("test"))
- {
- _logger.LogInformation("Migration worker stopped");
- }
-
- return base.StopAsync(cancellationToken);
- }
-}
diff --git a/src/Vertical.Slice.Template/Shared/Workers/SeedWorker.cs b/src/Vertical.Slice.Template/Shared/Workers/SeedWorker.cs
deleted file mode 100644
index 6194c05..0000000
--- a/src/Vertical.Slice.Template/Shared/Workers/SeedWorker.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
-
-namespace Vertical.Slice.Template.Shared.Workers;
-
-// https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
-// Hint: we can't guarantee execution order of our seeder before our test so we should apply it manually in tests
-public class SeedWorker : BackgroundService
-{
- private readonly IServiceScopeFactory _serviceScopeFactory;
- private readonly ILogger _logger;
- private readonly IWebHostEnvironment _webHostEnvironment;
-
- public SeedWorker(
- IServiceScopeFactory serviceScopeFactory,
- ILogger logger,
- IWebHostEnvironment webHostEnvironment
- )
- {
- _serviceScopeFactory = serviceScopeFactory;
- _logger = logger;
- _webHostEnvironment = webHostEnvironment;
- }
-
- protected override async Task ExecuteAsync(CancellationToken stoppingToken)
- {
- if (!_webHostEnvironment.IsEnvironment("test"))
- {
- _logger.LogInformation("Seed worker started");
-
- // https://stackoverflow.com/questions/38238043/how-and-where-to-call-database-ensurecreated-and-database-migrate
- // https://www.michalbialecki.com/2020/07/20/adding-entity-framework-core-5-migrations-to-net-5-project/
- using var serviceScope = _serviceScopeFactory.CreateScope();
- var seeders = serviceScope.ServiceProvider.GetServices();
-
- foreach (var seeder in seeders.OrderBy(x => x.Order))
- {
- _logger.LogInformation("Seeding '{Seed}' started...", seeder.GetType().Name);
- await seeder.SeedAllAsync(stoppingToken);
- _logger.LogInformation("Seeding '{Seed}' ended...", seeder.GetType().Name);
- }
- }
- }
-
- public override Task StopAsync(CancellationToken cancellationToken)
- {
- if (!_webHostEnvironment.IsEnvironment("test"))
- {
- _logger.LogInformation("Seed worker stopped");
- }
-
- return base.StopAsync(cancellationToken);
- }
-}
diff --git a/tests/Vertical.Slice.Template.ApiClientTests/Catalogs/CatalogsServiceCatalogsTests.cs b/tests/Vertical.Slice.Template.ApiClientTests/Catalogs/CatalogsServiceCatalogsTests.cs
index 0e70f8f..9bfc358 100644
--- a/tests/Vertical.Slice.Template.ApiClientTests/Catalogs/CatalogsServiceCatalogsTests.cs
+++ b/tests/Vertical.Slice.Template.ApiClientTests/Catalogs/CatalogsServiceCatalogsTests.cs
@@ -9,14 +9,11 @@
namespace Vertical.Slice.Template.ApiClientTests.Catalogs;
-public class CatalogsServiceCatalogsTests : CatalogsTestBase
+public class CatalogsServiceCatalogsTests(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : CatalogsTestBase(sharedFixture, outputHelper)
{
- public CatalogsServiceCatalogsTests(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-
[Fact]
[CategoryTrait(TestCategory.Integration)]
public async Task create_product_can_create_product_with_valid_data()
diff --git a/tests/Vertical.Slice.Template.ApiClientTests/Users/UserApiClientTests.cs b/tests/Vertical.Slice.Template.ApiClientTests/Users/UserApiClientTests.cs
index a7c5408..680ee24 100644
--- a/tests/Vertical.Slice.Template.ApiClientTests/Users/UserApiClientTests.cs
+++ b/tests/Vertical.Slice.Template.ApiClientTests/Users/UserApiClientTests.cs
@@ -1,9 +1,8 @@
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Api;
using Vertical.Slice.Template.Shared.Clients.Users;
-using Vertical.Slice.Template.Shared.Core.Paging;
-using Vertical.Slice.Template.Shared.Data;
using Vertical.Slice.Template.TestsShared.Fixtures;
using Vertical.Slice.Template.TestsShared.TestBase;
using Vertical.Slice.Template.TestsShared.XunitCategories;
@@ -12,13 +11,11 @@
namespace Vertical.Slice.Template.ApiClientTests.Users;
[Collection(IntegrationTestUsersCollection.Name)]
-public class UserApiClientTests : IntegrationTest
+public class UserApiClientTests(SharedFixture sharedFixture, ITestOutputHelper outputHelper)
+ : IntegrationTest(sharedFixture, outputHelper)
{
private IUsersHttpClient? _usersHttpClient;
- public UserApiClientTests(SharedFixture sharedFixture, ITestOutputHelper outputHelper)
- : base(sharedFixture, outputHelper) { }
-
public IUsersHttpClient UsersClient =>
_usersHttpClient ??= SharedFixture.ServiceProvider.GetRequiredService();
diff --git a/tests/Vertical.Slice.Template.ApiClientTests/Vertical.Slice.Template.ApiClientTests.csproj b/tests/Vertical.Slice.Template.ApiClientTests/Vertical.Slice.Template.ApiClientTests.csproj
index bec1f02..742a575 100644
--- a/tests/Vertical.Slice.Template.ApiClientTests/Vertical.Slice.Template.ApiClientTests.csproj
+++ b/tests/Vertical.Slice.Template.ApiClientTests/Vertical.Slice.Template.ApiClientTests.csproj
@@ -1,13 +1,5 @@
-
- Vertical.Slice.Template.ApiClientTests
- Vertical.Slice.Template.ApiClientTests
-
-
-
-
-
-
+
PreserveNewest
@@ -26,5 +18,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/tests/Vertical.Slice.Template.ContractTests/TestBase.cs b/tests/Vertical.Slice.Template.ContractTests/CatalogsIntegrationTestBase.cs
similarity index 60%
rename from tests/Vertical.Slice.Template.ContractTests/TestBase.cs
rename to tests/Vertical.Slice.Template.ContractTests/CatalogsIntegrationTestBase.cs
index b3d090a..68ac24f 100644
--- a/tests/Vertical.Slice.Template.ContractTests/TestBase.cs
+++ b/tests/Vertical.Slice.Template.ContractTests/CatalogsIntegrationTestBase.cs
@@ -6,13 +6,9 @@
namespace Vertical.Slice.Template.ContractTests;
-public class TestBase
- : IntegrationTestBase,
- IClassFixture>
-{
- public TestBase(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-}
+public class CatalogsIntegrationTestBase(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+)
+ : IntegrationTestBase(sharedFixture, outputHelper),
+ IClassFixture>;
diff --git a/tests/Vertical.Slice.Template.ContractTests/Products/ProductsTests.cs b/tests/Vertical.Slice.Template.ContractTests/Products/ProductsCatalogsIntegrationTests.cs
similarity index 94%
rename from tests/Vertical.Slice.Template.ContractTests/Products/ProductsTests.cs
rename to tests/Vertical.Slice.Template.ContractTests/Products/ProductsCatalogsIntegrationTests.cs
index e18d18d..76470c1 100644
--- a/tests/Vertical.Slice.Template.ContractTests/Products/ProductsTests.cs
+++ b/tests/Vertical.Slice.Template.ContractTests/Products/ProductsCatalogsIntegrationTests.cs
@@ -10,14 +10,11 @@
namespace Vertical.Slice.Template.ContractTests.Products;
-public class ProductsTests : TestBase
+public class ProductsCatalogsIntegrationTests(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : CatalogsIntegrationTestBase(sharedFixture, outputHelper)
{
- public ProductsTests(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-
[Fact]
[CategoryTrait(TestCategory.Integration)]
public async Task contracts_should_pass_for_create_product()
diff --git a/tests/Vertical.Slice.Template.ContractTests/Users/UsersApiTests.cs b/tests/Vertical.Slice.Template.ContractTests/Users/UsersApiTests.cs
index e90efff..e4e49a4 100644
--- a/tests/Vertical.Slice.Template.ContractTests/Users/UsersApiTests.cs
+++ b/tests/Vertical.Slice.Template.ContractTests/Users/UsersApiTests.cs
@@ -6,12 +6,7 @@ namespace Vertical.Slice.Template.ContractTests.Users;
public class UsersApiTests
{
- private readonly HttpClient _httpClient;
-
- public UsersApiTests()
- {
- _httpClient = new HttpClient { BaseAddress = new Uri("https://dummyjson.com"), };
- }
+ private readonly HttpClient _httpClient = new() { BaseAddress = new Uri("https://dummyjson.com") };
[Fact]
public async Task contracts_should_pass_for_get_character_by_id()
diff --git a/tests/Vertical.Slice.Template.ContractTests/Vertical.Slice.Template.ContractTests.csproj b/tests/Vertical.Slice.Template.ContractTests/Vertical.Slice.Template.ContractTests.csproj
index dc49975..6758d21 100644
--- a/tests/Vertical.Slice.Template.ContractTests/Vertical.Slice.Template.ContractTests.csproj
+++ b/tests/Vertical.Slice.Template.ContractTests/Vertical.Slice.Template.ContractTests.csproj
@@ -14,11 +14,10 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
diff --git a/tests/Vertical.Slice.Template.ContractTests/swagger.json b/tests/Vertical.Slice.Template.ContractTests/swagger.json
new file mode 100644
index 0000000..4cf5ef6
--- /dev/null
+++ b/tests/Vertical.Slice.Template.ContractTests/swagger.json
@@ -0,0 +1,393 @@
+{
+ "openapi": "3.0.1",
+ "info": {
+ "title": "Example API",
+ "description": "An example application with OpenAPI, Swashbuckle, and API versioning.",
+ "contact": {
+ "name": "Bill Mei",
+ "email": "bill.mei@somewhere.com"
+ },
+ "license": {
+ "name": "MIT",
+ "url": "https://opensource.org/licenses/MIT"
+ },
+ "version": "1.0"
+ },
+ "paths": {
+ "/api/v1/catalogs/products": {
+ "post": {
+ "tags": [
+ "Products",
+ "Products"
+ ],
+ "summary": "Creating a New Product",
+ "description": "Creating a New Product",
+ "operationId": "CreateProduct",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProductRequest"
+ }
+ }
+ },
+ "required": true
+ },
+ "responses": {
+ "201": {
+ "description": "Product created successfully.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/CreateProductResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid input for creating product.",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/HttpValidationProblemDetails"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "UnAuthorized request.",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ },
+ "get": {
+ "tags": [
+ "Products",
+ "Products"
+ ],
+ "summary": "Getting products by page info",
+ "description": "Getting products by page info",
+ "operationId": "GetProductsByPage",
+ "parameters": [
+ {
+ "name": "PageSize",
+ "in": "query",
+ "style": "form",
+ "schema": {
+ "type": "integer",
+ "format": "int32",
+ "default": 10
+ }
+ },
+ {
+ "name": "PageNumber",
+ "in": "query",
+ "style": "form",
+ "schema": {
+ "type": "integer",
+ "format": "int32",
+ "default": 1
+ }
+ },
+ {
+ "name": "Filters",
+ "in": "query",
+ "style": "form",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "SortOrder",
+ "in": "query",
+ "style": "form",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Products fetched successfully.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetGetProductsByPageResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid input for getting product.",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/HttpValidationProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/api/v1/catalogs/products/{id}": {
+ "get": {
+ "tags": [
+ "Products",
+ "Products"
+ ],
+ "summary": "Getting a product by id",
+ "description": "Getting a product by id",
+ "operationId": "GetProductById",
+ "parameters": [
+ {
+ "name": "id",
+ "in": "path",
+ "required": true,
+ "style": "simple",
+ "schema": {
+ "type": "string",
+ "format": "uuid"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Product fetched successfully.",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GetProductByIdResponse"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid input for getting product.",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/HttpValidationProblemDetails"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Product not found",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "CreateProductRequest": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true
+ },
+ "categoryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "price": {
+ "type": "number",
+ "format": "double"
+ },
+ "description": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "CreateProductResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ }
+ },
+ "additionalProperties": false
+ },
+ "GetGetProductsByPageResponse": {
+ "type": "object",
+ "properties": {
+ "products": {
+ "$ref": "#/components/schemas/ProductDtoIPageList"
+ }
+ },
+ "additionalProperties": false
+ },
+ "GetProductByIdResponse": {
+ "type": "object",
+ "properties": {
+ "product": {
+ "$ref": "#/components/schemas/ProductDto"
+ }
+ },
+ "additionalProperties": false
+ },
+ "HttpValidationProblemDetails": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "nullable": true
+ },
+ "title": {
+ "type": "string",
+ "nullable": true
+ },
+ "status": {
+ "type": "integer",
+ "format": "int32",
+ "nullable": true
+ },
+ "detail": {
+ "type": "string",
+ "nullable": true
+ },
+ "instance": {
+ "type": "string",
+ "nullable": true
+ },
+ "errors": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "nullable": true,
+ "readOnly": true
+ }
+ },
+ "additionalProperties": { }
+ },
+ "ProblemDetails": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "nullable": true
+ },
+ "title": {
+ "type": "string",
+ "nullable": true
+ },
+ "status": {
+ "type": "integer",
+ "format": "int32",
+ "nullable": true
+ },
+ "detail": {
+ "type": "string",
+ "nullable": true
+ },
+ "instance": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "additionalProperties": { }
+ },
+ "ProductDto": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "categoryId": {
+ "type": "string",
+ "format": "uuid"
+ },
+ "name": {
+ "type": "string",
+ "nullable": true
+ },
+ "price": {
+ "type": "number",
+ "format": "double"
+ },
+ "description": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "ProductDtoIPageList": {
+ "type": "object",
+ "properties": {
+ "currentPageSize": {
+ "type": "integer",
+ "format": "int32",
+ "readOnly": true
+ },
+ "currentStartIndex": {
+ "type": "integer",
+ "format": "int32",
+ "readOnly": true
+ },
+ "currentEndIndex": {
+ "type": "integer",
+ "format": "int32",
+ "readOnly": true
+ },
+ "totalPages": {
+ "type": "integer",
+ "format": "int32",
+ "readOnly": true
+ },
+ "hasPrevious": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "hasNext": {
+ "type": "boolean",
+ "readOnly": true
+ },
+ "items": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/ProductDto"
+ },
+ "nullable": true
+ },
+ "totalCount": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "pageNumber": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "pageSize": {
+ "type": "integer",
+ "format": "int32"
+ }
+ },
+ "additionalProperties": false
+ }
+ }
+ }
+}
diff --git a/tests/Vertical.Slice.Template.DependencyTests/DependencyTests.cs b/tests/Vertical.Slice.Template.DependencyTests/DependencyTests.cs
index 95d77aa..a42f5d8 100644
--- a/tests/Vertical.Slice.Template.DependencyTests/DependencyTests.cs
+++ b/tests/Vertical.Slice.Template.DependencyTests/DependencyTests.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
+using Shared.Core.Extensions.ServiceCollectionsExtensions;
using Vertical.Slice.Template.Api;
-using Vertical.Slice.Template.Shared.Core.Extensions.ServiceCollectionsExtensions;
using Vertical.Slice.Template.Shared.Data;
using Vertical.Slice.Template.TestsShared.Fixtures;
using Vertical.Slice.Template.TestsShared.XunitCategories;
diff --git a/tests/Vertical.Slice.Template.DependencyTests/Vertical.Slice.Template.DependencyTests.csproj b/tests/Vertical.Slice.Template.DependencyTests/Vertical.Slice.Template.DependencyTests.csproj
index 41c7497..e2f9689 100644
--- a/tests/Vertical.Slice.Template.DependencyTests/Vertical.Slice.Template.DependencyTests.csproj
+++ b/tests/Vertical.Slice.Template.DependencyTests/Vertical.Slice.Template.DependencyTests.csproj
@@ -1,10 +1,5 @@
-
-
-
-
-
PreserveNewest
@@ -19,5 +14,9 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/tests/Vertical.Slice.Template.EndToEndTests/Products/Feature/GettingProductById/GetProductByIdTests.cs b/tests/Vertical.Slice.Template.EndToEndTests/Products/Feature/GettingProductById/GetProductByIdTests.cs
index cf884ce..f10e867 100644
--- a/tests/Vertical.Slice.Template.EndToEndTests/Products/Feature/GettingProductById/GetProductByIdTests.cs
+++ b/tests/Vertical.Slice.Template.EndToEndTests/Products/Feature/GettingProductById/GetProductByIdTests.cs
@@ -1,13 +1,10 @@
-using System.Net.Http.Headers;
-using System.Net.Http.Json;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
+using Shared.Core.Exceptions;
using Vertical.Slice.Template.Api;
using Vertical.Slice.Template.Products.Features.GettingProductById.v1;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
using Vertical.Slice.Template.Shared.Data;
-using Vertical.Slice.Template.TestsShared.Extensions;
using Vertical.Slice.Template.TestsShared.Fakes.Products;
using Vertical.Slice.Template.TestsShared.Fixtures;
using Vertical.Slice.Template.TestsShared.XunitCategories;
@@ -15,14 +12,11 @@
namespace Vertical.Slice.Template.EndToEndTests.Products.Feature.GettingProductById;
-public class GetProductByIdTests : CatalogsEndToEndTestBase
+public class GetProductByIdTests(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : CatalogsEndToEndTestBase(sharedFixture, outputHelper)
{
- public GetProductByIdTests(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-
[Fact]
[CategoryTrait(TestCategory.EndToEnd)]
public async Task can_returns_ok_status_code_using_valid_id_and_auth_credentials()
diff --git a/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/CreatingProduct/v1/CreateProductTests.cs b/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/CreatingProduct/v1/CreateProductTests.cs
index 54ae5ac..f18b627 100644
--- a/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/CreatingProduct/v1/CreateProductTests.cs
+++ b/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/CreatingProduct/v1/CreateProductTests.cs
@@ -8,23 +8,16 @@
namespace Vertical.Slice.Template.IntegrationTests.Products.Features.CreatingProduct.v1;
-public class CreateProductTests : CatalogsIntegrationTestBase
+public class CreateProductTests(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : CatalogsIntegrationTestBase(sharedFixture, outputHelper)
{
- public CreateProductTests(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-
[Fact]
[CategoryTrait(TestCategory.Integration)]
public async Task should_create_new_product_with_valid_input_in_sql_db()
{
- InMemoryLogTrackerProvider.Logs.Errors.Should().BeEmpty();
- InMemoryLogTrackerProvider.Logs.Informations.Should().NotBeEmpty();
-
// Arrange
-
var fakeCategoryId = Guid.NewGuid();
var command = new CreateProductFake(fakeCategoryId).Generate();
diff --git a/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs b/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
index c2af7c5..65680fb 100644
--- a/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
+++ b/tests/Vertical.Slice.Template.IntegrationTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
@@ -1,8 +1,8 @@
using FluentAssertions;
+using Shared.Core.Exceptions;
using Vertical.Slice.Template.Api;
using Vertical.Slice.Template.Products.Features.GettingProductById.v1;
using Vertical.Slice.Template.Products.Models;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
using Vertical.Slice.Template.Shared.Data;
using Vertical.Slice.Template.TestsShared.Fakes.Products;
using Vertical.Slice.Template.TestsShared.Fixtures;
@@ -11,14 +11,11 @@
namespace Vertical.Slice.Template.IntegrationTests.Products.Features.GettingProductById.v1;
-public class GetProductByIdTests : CatalogsIntegrationTestBase
+public class GetProductByIdTests(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : CatalogsIntegrationTestBase(sharedFixture, outputHelper)
{
- public GetProductByIdTests(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper) { }
-
[Fact]
[CategoryTrait(TestCategory.Integration)]
internal async Task can_returns_valid_product_dto()
diff --git a/tests/Vertical.Slice.Template.IntegrationTests/Vertical.Slice.Template.IntegrationTests.csproj b/tests/Vertical.Slice.Template.IntegrationTests/Vertical.Slice.Template.IntegrationTests.csproj
index 84b12e1..242609e 100644
--- a/tests/Vertical.Slice.Template.IntegrationTests/Vertical.Slice.Template.IntegrationTests.csproj
+++ b/tests/Vertical.Slice.Template.IntegrationTests/Vertical.Slice.Template.IntegrationTests.csproj
@@ -1,9 +1,5 @@
-
-
-
-
PreserveNewest
@@ -20,12 +16,11 @@
-
-
+
-
+
diff --git a/tests/Vertical.Slice.Template.TestsShared/Factory/CustomWebApplicationFactory.cs b/tests/Vertical.Slice.Template.TestsShared/Factory/CustomWebApplicationFactory.cs
index aef53a2..01ea731 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Factory/CustomWebApplicationFactory.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Factory/CustomWebApplicationFactory.cs
@@ -5,7 +5,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Events;
using Serilog.Extensions.Logging;
@@ -13,10 +12,11 @@
namespace Vertical.Slice.Template.TestsShared.Factory;
-public class CustomWebApplicationFactory : WebApplicationFactory, IAsyncLifetime
+public class CustomWebApplicationFactory(Action? webHostBuilder = null)
+ : WebApplicationFactory,
+ IAsyncLifetime
{
private ITestOutputHelper? _outputHelper;
- private readonly Action? _webHostBuilder;
public Action? TestConfigureServices { get; set; }
@@ -27,11 +27,6 @@ public class CustomWebApplicationFactory : WebApplicationFactory
public InMemoryLoggerProvider InMemoryLogTrackerProvider { get; } = new();
- public CustomWebApplicationFactory(Action? webHostBuilder = null)
- {
- _webHostBuilder = webHostBuilder;
- }
-
protected override IHost CreateHost(IHostBuilder builder)
{
builder.UseEnvironment("test");
@@ -72,7 +67,7 @@ protected override IHost CreateHost(IHostBuilder builder)
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
- _webHostBuilder?.Invoke(builder);
+ webHostBuilder?.Invoke(builder);
builder.ConfigureAppConfiguration(
(hostingContext, configurationBuilder) =>
diff --git a/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductFake.cs b/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductFake.cs
index b07f882..24f7c5e 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductFake.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductFake.cs
@@ -3,7 +3,7 @@
namespace Vertical.Slice.Template.TestsShared.Fakes.Products;
-public sealed class CreateProductFake : AutoFaker
+internal sealed class CreateProductFake : AutoFaker
{
public CreateProductFake(Guid? categoryId = null)
{
diff --git a/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductRequestFake.cs b/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductRequestFake.cs
index f216f28..3e622d4 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductRequestFake.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Fakes/Products/CreateProductRequestFake.cs
@@ -3,7 +3,7 @@
namespace Vertical.Slice.Template.TestsShared.Fakes.Products;
-public sealed class CreateProductRequestFake : AutoFaker
+internal sealed class CreateProductRequestFake : AutoFaker
{
public CreateProductRequestFake(Guid? categoryId = null)
{
diff --git a/tests/Vertical.Slice.Template.TestsShared/Fixtures/MsSqlContainerFixture.cs b/tests/Vertical.Slice.Template.TestsShared/Fixtures/MsSqlContainerFixture.cs
index d3473aa..e56dc27 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Fixtures/MsSqlContainerFixture.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Fixtures/MsSqlContainerFixture.cs
@@ -1,7 +1,7 @@
using Microsoft.Data.SqlClient;
using Respawn;
+using Shared.Core.Extensions;
using Testcontainers.MsSql;
-using Vertical.Slice.Template.Shared.Core.Extensions;
using Xunit.Sdk;
namespace Vertical.Slice.Template.TestsShared.Fixtures;
diff --git a/tests/Vertical.Slice.Template.TestsShared/Fixtures/PostgresContainerFixture.cs b/tests/Vertical.Slice.Template.TestsShared/Fixtures/PostgresContainerFixture.cs
index 2fe5f80..d53652d 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Fixtures/PostgresContainerFixture.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Fixtures/PostgresContainerFixture.cs
@@ -1,8 +1,7 @@
-using Dapper;
using Npgsql;
using Respawn;
+using Shared.Core.Extensions;
using Testcontainers.PostgreSql;
-using Vertical.Slice.Template.Shared.Core.Extensions;
using Vertical.Slice.Template.TestsShared.Helpers;
using Xunit.Sdk;
diff --git a/tests/Vertical.Slice.Template.TestsShared/Fixtures/SharedFixture.cs b/tests/Vertical.Slice.Template.TestsShared/Fixtures/SharedFixture.cs
index 1bf5a81..0ff42a8 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Fixtures/SharedFixture.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Fixtures/SharedFixture.cs
@@ -1,6 +1,5 @@
using System.Net.Http.Headers;
using AutoBogus;
-using DotNet.Testcontainers.Configurations;
using FluentAssertions;
using FluentAssertions.Extensions;
using MediatR;
@@ -9,7 +8,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
-using Vertical.Slice.Template.Shared.EF;
+using Shared.EF;
using Vertical.Slice.Template.TestsShared.Factory;
using Xunit.Sdk;
@@ -77,7 +76,7 @@ public SharedFixture(IMessageSink messageSink)
{
$"{nameof(PostgresOptions)}:{nameof(PostgresOptions.ConnectionString)}",
PostgresContainerFixture.Container.GetConnectionString()
- }
+ },
};
// add in-memory configuration instead of using appestings.json and override existing settings and it is accessible via IOptions and Configuration
diff --git a/tests/Vertical.Slice.Template.TestsShared/Helpers/ConfigurationHelper.cs b/tests/Vertical.Slice.Template.TestsShared/Helpers/ConfigurationHelper.cs
index 8e04206..5bbc8af 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Helpers/ConfigurationHelper.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/Helpers/ConfigurationHelper.cs
@@ -1,6 +1,5 @@
using Microsoft.Extensions.Configuration;
-using Vertical.Slice.Template.Shared.Core.Extensions;
-using Vertical.Slice.Template.Shared.Web.Extensions;
+using Shared.Core.Extensions;
namespace Vertical.Slice.Template.TestsShared.Helpers;
diff --git a/tests/Vertical.Slice.Template.TestsShared/TestBase/EndToEndTestBase.cs b/tests/Vertical.Slice.Template.TestsShared/TestBase/EndToEndTestBase.cs
index f4779c3..983fbfa 100644
--- a/tests/Vertical.Slice.Template.TestsShared/TestBase/EndToEndTestBase.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/TestBase/EndToEndTestBase.cs
@@ -3,25 +3,16 @@
namespace Vertical.Slice.Template.TestsShared.TestBase;
-public class EndToEndTestTest : IntegrationTest
- where TEntryPoint : class
-{
- public EndToEndTestTest(SharedFixture sharedFixture, ITestOutputHelper outputHelper)
- : base(sharedFixture, outputHelper) { }
-}
+public class EndToEndTestTest(SharedFixture sharedFixture, ITestOutputHelper outputHelper)
+ : IntegrationTest(sharedFixture, outputHelper)
+ where TEntryPoint : class;
-public abstract class EndToEndTestTestBase : EndToEndTestTest
+public abstract class EndToEndTestTestBase(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : EndToEndTestTest(sharedFixture, outputHelper)
where TEntryPoint : class
where TContext : DbContext
{
- protected EndToEndTestTestBase(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper)
- {
- SharedFixture = sharedFixture;
- }
-
- public new SharedFixtureWithEfCore SharedFixture { get; }
+ public new SharedFixtureWithEfCore SharedFixture { get; } = sharedFixture;
}
diff --git a/tests/Vertical.Slice.Template.TestsShared/TestBase/IntegrationTestBase.cs b/tests/Vertical.Slice.Template.TestsShared/TestBase/IntegrationTestBase.cs
index 0776f9d..01ff8aa 100644
--- a/tests/Vertical.Slice.Template.TestsShared/TestBase/IntegrationTestBase.cs
+++ b/tests/Vertical.Slice.Template.TestsShared/TestBase/IntegrationTestBase.cs
@@ -1,34 +1,33 @@
-using Meziantou.Extensions.Logging.InMemory;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Vertical.Slice.Template.Shared.Abstractions.Ef;
+using Shared.Abstractions.Persistence;
+using Shared.Abstractions.Persistence.Ef;
using Vertical.Slice.Template.TestsShared.Fixtures;
namespace Vertical.Slice.Template.TestsShared.TestBase;
+//https://bartwullems.blogspot.com/2019/09/xunit-async-lifetime.html
+//https://www.danclarke.com/cleaner-tests-with-iasynclifetime
+//https://xunit.net/docs/shared-context
public abstract class IntegrationTest : XunitContextBase, IAsyncLifetime
where TEntryPoint : class
{
- private readonly ITestOutputHelper _outputHelper;
+ private IServiceScope? _serviceScope;
+
protected CancellationToken CancellationToken => CancellationTokenSource.Token;
protected CancellationTokenSource CancellationTokenSource { get; }
protected int Timeout => 180;
- protected IServiceScope Scope { get; }
- protected SharedFixture SharedFixture { get; }
- ///
- /// Use for tracking occured log events for testing purposes
- ///
- protected InMemoryLoggerProvider InMemoryLogTrackerProvider { get; }
+ // Build Service Provider here
+ protected IServiceScope Scope => _serviceScope ??= SharedFixture.ServiceProvider.CreateScope();
+ protected SharedFixture SharedFixture { get; }
protected IntegrationTest(SharedFixture sharedFixture, ITestOutputHelper outputHelper)
: base(outputHelper)
{
- _outputHelper = outputHelper;
SharedFixture = sharedFixture;
-
SharedFixture.SetOutputHelper(outputHelper);
CancellationTokenSource = new(TimeSpan.FromSeconds(Timeout));
@@ -42,26 +41,24 @@ protected IntegrationTest(SharedFixture sharedFixture, ITestOutputH
RegisterTestAppConfigurations(configurationBuilder, context.Configuration, context.HostingEnvironment);
}
);
-
- // Build Service Provider here
- Scope = SharedFixture.ServiceProvider.CreateScope();
- InMemoryLogTrackerProvider = sharedFixture.Factory.InMemoryLogTrackerProvider;
}
- protected virtual void RegisterTestConfigureServices(IServiceCollection services) { }
-
- protected virtual void RegisterTestAppConfigurations(
- IConfigurationBuilder builder,
- IConfiguration configuration,
- IHostEnvironment environment
- ) { }
-
// we use IAsyncLifetime in xunit instead of constructor when we have async operation
public virtual async Task InitializeAsync()
{
await RunSeedAndMigrationAsync();
}
+ public virtual async Task DisposeAsync()
+ {
+ // it is better messages delete first
+ await SharedFixture.ResetDatabasesAsync(CancellationToken);
+
+ await CancellationTokenSource.CancelAsync();
+
+ Scope.Dispose();
+ }
+
private async Task RunSeedAndMigrationAsync()
{
var migrations = Scope.ServiceProvider.GetServices();
@@ -87,29 +84,21 @@ private async Task RunSeedAndMigrationAsync()
}
}
- public virtual async Task DisposeAsync()
- {
- // it is better messages delete first
- await SharedFixture.ResetDatabasesAsync(CancellationToken);
-
- await CancellationTokenSource.CancelAsync();
+ protected virtual void RegisterTestConfigureServices(IServiceCollection services) { }
- Scope.Dispose();
- }
+ protected virtual void RegisterTestAppConfigurations(
+ IConfigurationBuilder builder,
+ IConfiguration configuration,
+ IHostEnvironment environment
+ ) { }
}
-public abstract class IntegrationTestBase : IntegrationTest
+public abstract class IntegrationTestBase(
+ SharedFixtureWithEfCore sharedFixture,
+ ITestOutputHelper outputHelper
+) : IntegrationTest(sharedFixture, outputHelper)
where TEntryPoint : class
where TContext : DbContext
{
- protected IntegrationTestBase(
- SharedFixtureWithEfCore sharedFixture,
- ITestOutputHelper outputHelper
- )
- : base(sharedFixture, outputHelper)
- {
- SharedFixture = sharedFixture;
- }
-
- public new SharedFixtureWithEfCore SharedFixture { get; }
+ public new SharedFixtureWithEfCore SharedFixture { get; } = sharedFixture;
}
diff --git a/tests/Vertical.Slice.Template.TestsShared/Vertical.Slice.Template.TestsShared.csproj b/tests/Vertical.Slice.Template.TestsShared/Vertical.Slice.Template.TestsShared.csproj
index e6a24cc..d7fe958 100644
--- a/tests/Vertical.Slice.Template.TestsShared/Vertical.Slice.Template.TestsShared.csproj
+++ b/tests/Vertical.Slice.Template.TestsShared/Vertical.Slice.Template.TestsShared.csproj
@@ -36,8 +36,15 @@
-
-
+
+
+
+
+
+
+
+
+
diff --git a/tests/Vertical.Slice.Template.UnitTests/Common/CatalogsUnitTestBase.cs b/tests/Vertical.Slice.Template.UnitTests/Common/CatalogsUnitTestBase.cs
index ee87bbe..979749a 100644
--- a/tests/Vertical.Slice.Template.UnitTests/Common/CatalogsUnitTestBase.cs
+++ b/tests/Vertical.Slice.Template.UnitTests/Common/CatalogsUnitTestBase.cs
@@ -1,8 +1,8 @@
using AutoMapper;
using FluentValidation;
using Microsoft.Extensions.Options;
+using Shared.Core.Paging;
using Sieve.Models;
-using Vertical.Slice.Template.Shared.Core.Paging;
using Vertical.Slice.Template.TestsShared.XunitCategories;
namespace Vertical.Slice.Template.UnitTests.Common;
diff --git a/tests/Vertical.Slice.Template.UnitTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs b/tests/Vertical.Slice.Template.UnitTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
index 6876b32..bacfc3e 100644
--- a/tests/Vertical.Slice.Template.UnitTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
+++ b/tests/Vertical.Slice.Template.UnitTests/Products/Features/GettingProductById/v1/GetProductByIdTests.cs
@@ -1,9 +1,9 @@
using AutoBogus;
using FluentAssertions;
using NSubstitute;
+using Shared.Core.Exceptions;
using Vertical.Slice.Template.Products.Features.GettingProductById.v1;
using Vertical.Slice.Template.Products.ReadModel;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
using Vertical.Slice.Template.TestsShared.XunitCategories;
using Vertical.Slice.Template.UnitTests.Common;
diff --git a/tests/Vertical.Slice.Template.UnitTests/Shared/UserHttpClientTests.cs b/tests/Vertical.Slice.Template.UnitTests/Shared/UserHttpClientTests.cs
index c0c6331..a7e353c 100644
--- a/tests/Vertical.Slice.Template.UnitTests/Shared/UserHttpClientTests.cs
+++ b/tests/Vertical.Slice.Template.UnitTests/Shared/UserHttpClientTests.cs
@@ -5,24 +5,17 @@
using Newtonsoft.Json;
using NSubstitute;
using RichardSzalay.MockHttp;
+using Shared.Core.Exceptions;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Shared.Clients.Users;
using Vertical.Slice.Template.Shared.Clients.Users.Dtos;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
-using Vertical.Slice.Template.Shared.Core.Paging;
using Vertical.Slice.Template.UnitTests.Common;
using Vertical.Slice.Template.Users.Models;
namespace Vertical.Slice.Template.UnitTests.Shared;
-public class UserHttpClientTests : IClassFixture
+public class UserHttpClientTests(MappingFixture mappingFixture) : IClassFixture
{
- private readonly MappingFixture _mappingFixture;
-
- public UserHttpClientTests(MappingFixture mappingFixture)
- {
- _mappingFixture = mappingFixture;
- }
-
[Fact]
public async Task get_all_users_should_call_http_client_with_valid_parameters_once()
{
@@ -33,36 +26,37 @@ public async Task get_all_users_should_call_http_client_with_valid_parameters_on
var options = Substitute.For>();
var usersHttpClientOptions = new UsersHttpClientOptions
- {
- UsersEndpoint = "users", BaseAddress = "http://example.com"
- };
+ {
+ UsersEndpoint = "users",
+ BaseAddress = "http://example.com",
+ };
options.Value.Returns(usersHttpClientOptions);
- var url =
- $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
+ var url = $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
var usersClient = new AutoFaker().Generate(total);
var usersListPage = new UsersListPageClientDto
- {
- Total = total, Limit = pageSize, Skip = page, Users = usersClient
- };
+ {
+ Total = total,
+ Limit = pageSize,
+ Skip = page,
+ Users = usersClient,
+ };
// https://github.com/richardszalay/mockhttp
// https://code-maze.com/csharp-mock-httpclient-with-unit-tests/
var mockHttp = new MockHttpMessageHandler();
// Setup a respond for the user api (including a wildcard in the URL)
- var request =
- mockHttp.When(url)
- .Respond("application/json", JsonConvert.SerializeObject(usersListPage)); // Respond with JSON
+ var request = mockHttp.When(url).Respond("application/json", JsonConvert.SerializeObject(usersListPage)); // Respond with JSON
// Inject the handler or client into your application code
var client = mockHttp.ToHttpClient();
client.BaseAddress = new Uri(usersHttpClientOptions.BaseAddress);
- var pageRequest = new PageRequest {PageNumber = page, PageSize = pageSize};
+ var pageRequest = new PageRequest { PageNumber = page, PageSize = pageSize };
- var usersHttpClient = new UsersHttpClient(client, _mappingFixture.Mapper, options);
+ var usersHttpClient = new UsersHttpClient(client, mappingFixture.Mapper, options);
// Act
await usersHttpClient.GetAllUsersAsync(pageRequest);
@@ -81,40 +75,41 @@ public async Task get_all_users_should_return_users_list()
var options = Substitute.For>();
var usersHttpClientOptions = new UsersHttpClientOptions
- {
- UsersEndpoint = "users", BaseAddress = "http://example.com"
- };
+ {
+ UsersEndpoint = "users",
+ BaseAddress = "http://example.com",
+ };
options.Value.Returns(usersHttpClientOptions);
- var url =
- $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
+ var url = $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
var usersClient = new AutoFaker().Generate(total);
var usersListPage = new UsersListPageClientDto
- {
- Total = total, Limit = pageSize, Skip = page, Users = usersClient
- };
+ {
+ Total = total,
+ Limit = pageSize,
+ Skip = page,
+ Users = usersClient,
+ };
// https://github.com/richardszalay/mockhttp
// https://code-maze.com/csharp-mock-httpclient-with-unit-tests/
var mockHttp = new MockHttpMessageHandler();
// Setup a respond for the user api (including a wildcard in the URL)
- var request =
- mockHttp.When(url)
- .Respond("application/json", JsonConvert.SerializeObject(usersListPage)); // Respond with JSON
+ var request = mockHttp.When(url).Respond("application/json", JsonConvert.SerializeObject(usersListPage)); // Respond with JSON
// Inject the handler or client into your application code
var client = mockHttp.ToHttpClient();
client.BaseAddress = new Uri(usersHttpClientOptions.BaseAddress);
- var pageRequest = new PageRequest {PageNumber = page, PageSize = pageSize};
+ var pageRequest = new PageRequest { PageNumber = page, PageSize = pageSize };
- var users = _mappingFixture.Mapper.Map>(usersClient);
+ var users = mappingFixture.Mapper.Map>(usersClient);
var expectedPageList = new PageList(users.ToList(), page, pageSize, total);
- var usersHttpClient = new UsersHttpClient(client, _mappingFixture.Mapper, options);
+ var usersHttpClient = new UsersHttpClient(client, mappingFixture.Mapper, options);
// Act
var result = await usersHttpClient.GetAllUsersAsync(pageRequest);
@@ -132,24 +127,26 @@ public async Task get_all_users_with_http_response_exception_should_throw_http_r
var options = Substitute.For>();
var usersHttpClientOptions = new UsersHttpClientOptions
- {
- UsersEndpoint = "users", BaseAddress = "http://example.com"
- };
+ {
+ UsersEndpoint = "users",
+ BaseAddress = "http://example.com",
+ };
options.Value.Returns(usersHttpClientOptions);
// https://github.com/richardszalay/mockhttp
// https://code-maze.com/csharp-mock-httpclient-with-unit-tests/
var mockHttp = new MockHttpMessageHandler();
mockHttp.Fallback.Throw(
- new HttpResponseException(StatusCodes.Status500InternalServerError, "There is an error in the server"));
+ new HttpResponseException(StatusCodes.Status500InternalServerError, "There is an error in the server")
+ );
// Inject the handler or client into your application code
var client = mockHttp.ToHttpClient();
client.BaseAddress = new Uri(usersHttpClientOptions.BaseAddress);
- var pageRequest = new PageRequest {PageNumber = page, PageSize = pageSize};
+ var pageRequest = new PageRequest { PageNumber = page, PageSize = pageSize };
- var usersHttpClient = new UsersHttpClient(client, _mappingFixture.Mapper, options);
+ var usersHttpClient = new UsersHttpClient(client, mappingFixture.Mapper, options);
// Act
Func act = () => usersHttpClient.GetAllUsersAsync(pageRequest);
@@ -167,28 +164,27 @@ public async Task get_all_users_with_exception_should_throw_exception()
var options = Substitute.For>();
var usersHttpClientOptions = new UsersHttpClientOptions
- {
- UsersEndpoint = "users", BaseAddress = "http://example.com"
- };
+ {
+ UsersEndpoint = "users",
+ BaseAddress = "http://example.com",
+ };
options.Value.Returns(usersHttpClientOptions);
- var url =
- $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
+ var url = $"{usersHttpClientOptions.BaseAddress}/{usersHttpClientOptions.UsersEndpoint}*";
// https://github.com/richardszalay/mockhttp
// https://code-maze.com/csharp-mock-httpclient-with-unit-tests/
var mockHttp = new MockHttpMessageHandler();
// Setup a response for the user api (including a wildcard in the URL)
- var request =
- mockHttp.When(url).Respond("application/json", JsonConvert.SerializeObject(null)); // Respond with JSON
+ var request = mockHttp.When(url).Respond("application/json", JsonConvert.SerializeObject(null)); // Respond with JSON
// Inject the handler or client into your application code
var client = mockHttp.ToHttpClient();
client.BaseAddress = new Uri(usersHttpClientOptions.BaseAddress);
- var pageRequest = new PageRequest {PageNumber = page, PageSize = pageSize};
+ var pageRequest = new PageRequest { PageNumber = page, PageSize = pageSize };
- var usersHttpClient = new UsersHttpClient(client, _mappingFixture.Mapper, options);
+ var usersHttpClient = new UsersHttpClient(client, mappingFixture.Mapper, options);
// Act
Func act = () => usersHttpClient.GetAllUsersAsync(pageRequest);
diff --git a/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/GetUsersEndpointTests.cs b/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/v1/GetUsersEndpointTests.cs
similarity index 100%
rename from tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/GetUsersEndpointTests.cs
rename to tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/v1/GetUsersEndpointTests.cs
diff --git a/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/GetUsersHandlerTests.cs b/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/v1/GetUsersHandlerTests.cs
similarity index 83%
rename from tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/GetUsersHandlerTests.cs
rename to tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/v1/GetUsersHandlerTests.cs
index d745d9c..5f45f0e 100644
--- a/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/GetUsersHandlerTests.cs
+++ b/tests/Vertical.Slice.Template.UnitTests/Users/Features/GetUsers/v1/GetUsersHandlerTests.cs
@@ -2,27 +2,20 @@
using FluentAssertions;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
+using Shared.Core.Exceptions;
+using Shared.Core.Paging;
using Vertical.Slice.Template.Shared.Clients.Users;
-using Vertical.Slice.Template.Shared.Core.Exceptions;
-using Vertical.Slice.Template.Shared.Core.Paging;
using Vertical.Slice.Template.UnitTests.Common;
using Vertical.Slice.Template.Users.Dtos;
using Vertical.Slice.Template.Users.GetUsers;
using Vertical.Slice.Template.Users.Models;
-namespace TDDSample.Tests.UnitTests.Users.Features.GetUsers;
+namespace Vertical.Slice.Template.UnitTests.Users.Features.GetUsers.v1;
// https://www.testwithspring.com/lesson/the-best-practices-of-nested-unit-tests/
-public class GetUsersHandlerTests : IClassFixture
+public class GetUsersHandlerTests(MappingFixture mappingFixture) : IClassFixture
{
- private readonly MappingFixture _mappingFixture;
-
- public GetUsersHandlerTests(MappingFixture mappingFixture)
- {
- _mappingFixture = mappingFixture;
- }
-
[Fact]
public async Task handle_should_call_users_http_client_once()
{
@@ -36,7 +29,7 @@ public async Task handle_should_call_users_http_client_once()
usersHttpClient.GetAllUsersAsync(Arg.Any(), cancellationToken).Returns(pageResult);
- var handler = new GetUsersHandler(usersHttpClient, _mappingFixture.Mapper);
+ var handler = new GetUsersHandler(usersHttpClient, mappingFixture.Mapper);
var query = GetUsersByPage.Of(new PageRequest { PageNumber = page, PageSize = pageSize });
await handler.Handle(query, cancellationToken);
@@ -57,7 +50,7 @@ public async Task handle_with_valid_request_should_returns_users()
usersHttpClient.GetAllUsersAsync(Arg.Any(), cancellationToken).Returns(pageResult);
- var handler = new GetUsersHandler(usersHttpClient, _mappingFixture.Mapper);
+ var handler = new GetUsersHandler(usersHttpClient, mappingFixture.Mapper);
var query = GetUsersByPage.Of(new PageRequest { PageNumber = page, PageSize = pageSize });
var result = await handler.Handle(query, cancellationToken);
@@ -84,7 +77,7 @@ public async Task handle_with_http_response_exception_should_returns_correct_err
.GetAllUsersAsync(Arg.Any(), cancellationToken)
.ThrowsAsync(new HttpResponseException(404, "Not Found"));
- var handler = new GetUsersHandler(usersHttpClient, _mappingFixture.Mapper);
+ var handler = new GetUsersHandler(usersHttpClient, mappingFixture.Mapper);
var query = GetUsersByPage.Of(new PageRequest { PageNumber = page, PageSize = pageSize });
@@ -105,7 +98,7 @@ public async Task handle_with_exception_should_returns_correct_error_result()
.GetAllUsersAsync(Arg.Any(), cancellationToken)
.ThrowsAsync(new Exception("Internal server error"));
- var handler = new GetUsersHandler(usersHttpClient, _mappingFixture.Mapper);
+ var handler = new GetUsersHandler(usersHttpClient, mappingFixture.Mapper);
var query = GetUsersByPage.Of(new PageRequest { PageNumber = page, PageSize = pageSize });
var act = () => handler.Handle(query, cancellationToken);
diff --git a/version.json b/version.json
index ef3fcd8..dbde95e 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "1.3.2-preview.2",
+ "version": "1.3.2",
"gitCommitIdShortAutoMinimum": 7,
"nugetPackageVersion": {
"semVer": 2