diff --git a/.github/workflows/dependency-updates.yml b/.github/workflows/dependency-updates.yml
index 75c228e..460aa03 100644
--- a/.github/workflows/dependency-updates.yml
+++ b/.github/workflows/dependency-updates.yml
@@ -53,7 +53,7 @@ jobs:
branch: "update/${{ env.date }}"
labels: dependencies
delete-branch: true
- commit-message: "Update packages"
+ commit-message: "chore: Update dependencies"
assignees: ${{ env.assignee }}
base: ${{ env.baseBranch }}
title: "Automatic Package Update ${{ env.date }}"
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 1a043db..0c6027b 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -1,4 +1,4 @@
-name: CI
+name: CI/CD
on:
workflow_dispatch:
@@ -7,25 +7,59 @@ on:
pull_request:
branches: [ main ]
+env:
+ DOCKER_IMAGE: alexdev28/clean-architecture
+
jobs:
build:
-
runs-on: ubuntu-latest
+ env:
+ solutionFile: CleanArchitecture.sln
+ projectName: CleanArchitecture
steps:
- uses: actions/checkout@v3
- - name: Dependency Review
- uses: actions/dependency-review-action@v3
- with:
- base-ref: ${{ github.event.pull_request.base.sha || 'main' }}
- head-ref: ${{ github.event.pull_request.head.sha || github.ref }}
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 8.x.x
+ dotnet-version: |
+ 8.x.x
+ # 6.x.x
+ # - name: Check for vulnerabilities
+ # run: |
+ # VERSION=$(curl -s https://jeremylong.github.io/DependencyCheck/current.txt)
+ # curl -Ls "https://github.com/jeremylong/DependencyCheck/releases/download/v$VERSION/dependency-check-$VERSION-release.zip" --output dependency-check.zip
+ # unzip dependency-check.zip
+ # ./dependency-check/bin/dependency-check.sh -s "**/*.csproj" --project "${{ env.projectName }}" --failOnCVSS "7"
+ # - name: Check for license issues
+ # run: |
+ # dotnet new tool-manifest
+ # dotnet tool install --local liz.tool
+ # dotnet liz "${{ env.solutionFile }}" --suppress-progressbar
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
+
+ docker:
+ runs-on: ubuntu-latest
+ needs: build
+ if: github.ref == 'refs/heads/main'
+ steps:
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Login to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+ - name: Build and push
+ uses: docker/build-push-action@v5
+ with:
+ # platforms: linux/amd64,linux/arm64
+ push: true
+ tags: ${{ env.DOCKER_IMAGE }}:latest
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 0899f53..ffb2b90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ riderModule.iml
.idea
.vs
CleanArchitecture.sln.DotSettings.user
+.DS_Store
\ No newline at end of file
diff --git a/CleanArchitecture.Api/CleanArchitecture.Api.csproj b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
index 7fb8080..9769426 100644
--- a/CleanArchitecture.Api/CleanArchitecture.Api.csproj
+++ b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
@@ -9,18 +9,18 @@
-
+
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
diff --git a/CleanArchitecture.Api/Controllers/TenantController.cs b/CleanArchitecture.Api/Controllers/TenantController.cs
index 4a312eb..8caf488 100644
--- a/CleanArchitecture.Api/Controllers/TenantController.cs
+++ b/CleanArchitecture.Api/Controllers/TenantController.cs
@@ -37,7 +37,8 @@ public sealed class TenantController : ApiController
[FromQuery] PageQuery query,
[FromQuery] string searchTerm = "",
[FromQuery] bool includeDeleted = false,
- [FromQuery, SortableFieldsAttribute] SortQuery? sortQuery = null)
+ [FromQuery] [SortableFieldsAttribute]
+ SortQuery? sortQuery = null)
{
var tenants = await _tenantService.GetAllTenantsAsync(
query,
diff --git a/CleanArchitecture.Api/Controllers/UserController.cs b/CleanArchitecture.Api/Controllers/UserController.cs
index 6e12fea..9a0f9e3 100644
--- a/CleanArchitecture.Api/Controllers/UserController.cs
+++ b/CleanArchitecture.Api/Controllers/UserController.cs
@@ -37,7 +37,8 @@ public sealed class UserController : ApiController
[FromQuery] PageQuery query,
[FromQuery] string searchTerm = "",
[FromQuery] bool includeDeleted = false,
- [FromQuery, SortableFieldsAttribute] SortQuery? sortQuery = null)
+ [FromQuery] [SortableFieldsAttribute]
+ SortQuery? sortQuery = null)
{
var users = await _userService.GetAllUsersAsync(
query,
diff --git a/CleanArchitecture.Api/Swagger/SortableFieldsAttribute.cs b/CleanArchitecture.Api/Swagger/SortableFieldsAttribute.cs
index 83cca2d..9774efd 100644
--- a/CleanArchitecture.Api/Swagger/SortableFieldsAttribute.cs
+++ b/CleanArchitecture.Api/Swagger/SortableFieldsAttribute.cs
@@ -4,7 +4,7 @@ using CleanArchitecture.Application.ViewModels.Sorting;
namespace CleanArchitecture.Api.Swagger;
-[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
+[AttributeUsage(AttributeTargets.Parameter)]
public sealed class SortableFieldsAttribute
: SwaggerSortableFieldsAttribute
where TSortingProvider : ISortingExpressionProvider, new()
diff --git a/CleanArchitecture.Api/Swagger/SortableFieldsAttributeFilter.cs b/CleanArchitecture.Api/Swagger/SortableFieldsAttributeFilter.cs
index d628229..6dd403c 100644
--- a/CleanArchitecture.Api/Swagger/SortableFieldsAttributeFilter.cs
+++ b/CleanArchitecture.Api/Swagger/SortableFieldsAttributeFilter.cs
@@ -26,7 +26,6 @@ public sealed class SortableFieldsAttributeFilter : IParameterFilter
var description = string.Join("
", attribute.GetFields().Order());
parameter.Description = $"{parameter.Description}
" +
- $"**Allowed values:**
{description}";
+ $"**Allowed values:**
{description}";
}
-}
-
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Api/Swagger/SwaggerSortableFieldsAttribute.cs b/CleanArchitecture.Api/Swagger/SwaggerSortableFieldsAttribute.cs
index 1dff29d..e3545a5 100644
--- a/CleanArchitecture.Api/Swagger/SwaggerSortableFieldsAttribute.cs
+++ b/CleanArchitecture.Api/Swagger/SwaggerSortableFieldsAttribute.cs
@@ -6,4 +6,4 @@ namespace CleanArchitecture.Api.Swagger;
public abstract class SwaggerSortableFieldsAttribute : Attribute
{
public abstract IEnumerable GetFields();
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
index b169280..46c6cda 100644
--- a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
+++ b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
@@ -8,12 +8,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,8 +24,8 @@
-
-
+
+
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Tenants/GetTenantByIdTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Tenants/GetTenantByIdTestFixture.cs
index e5d0622..47a35ea 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Tenants/GetTenantByIdTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Tenants/GetTenantByIdTestFixture.cs
@@ -1,9 +1,7 @@
using System;
-using System.Collections.Generic;
using CleanArchitecture.Application.Queries.Tenants.GetTenantById;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Domain.Interfaces.Repositories;
-using MockQueryable.NSubstitute;
using NSubstitute;
namespace CleanArchitecture.Application.Tests.Fixtures.Queries.Tenants;
@@ -30,9 +28,11 @@ public sealed class GetTenantByIdTestFixture : QueryHandlerBaseFixture
{
tenant.Delete();
}
+ else
+ {
+ TenantRepository.GetByIdAsync(Arg.Is(y => y == tenant.Id)).Returns(tenant);
+ }
- var tenantList = new List { tenant }.BuildMock();
- TenantRepository.GetAllNoTracking().Returns(tenantList);
return tenant;
}
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
index 9464fed..60305bf 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
@@ -35,7 +35,7 @@ public sealed class GetUserByIdTestFixture : QueryHandlerBaseFixture
var query = new[] { user }.BuildMock();
- UserRepository.GetAllNoTracking().Returns(query);
+ UserRepository.GetByIdAsync(Arg.Is(y => y == ExistingUserId)).Returns(user);
}
public void SetupDeletedUserAsync()
diff --git a/CleanArchitecture.Application/CleanArchitecture.Application.csproj b/CleanArchitecture.Application/CleanArchitecture.Application.csproj
index c251147..4e70f41 100644
--- a/CleanArchitecture.Application/CleanArchitecture.Application.csproj
+++ b/CleanArchitecture.Application/CleanArchitecture.Application.csproj
@@ -6,12 +6,12 @@
-
+
-
-
+
+
diff --git a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs
index a097c13..9f46f18 100644
--- a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs
@@ -32,7 +32,8 @@ public sealed class GetAllTenantsQueryHandler :
{
var tenantsQuery = _tenantRepository
.GetAllNoTracking()
- .Include(x => x.Users)
+ .IgnoreQueryFilters()
+ .Include(x => x.Users.Where(y => request.IncludeDeleted || !y.Deleted))
.Where(x => request.IncludeDeleted || !x.Deleted);
if (!string.IsNullOrWhiteSpace(request.SearchTerm))
diff --git a/CleanArchitecture.Application/Queries/Tenants/GetTenantById/GetTenantByIdQueryHandler.cs b/CleanArchitecture.Application/Queries/Tenants/GetTenantById/GetTenantByIdQueryHandler.cs
index 652c458..ddc25bf 100644
--- a/CleanArchitecture.Application/Queries/Tenants/GetTenantById/GetTenantByIdQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Tenants/GetTenantById/GetTenantByIdQueryHandler.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CleanArchitecture.Application.ViewModels.Tenants;
@@ -7,7 +6,6 @@ using CleanArchitecture.Domain.Interfaces;
using CleanArchitecture.Domain.Interfaces.Repositories;
using CleanArchitecture.Domain.Notifications;
using MediatR;
-using Microsoft.EntityFrameworkCore;
namespace CleanArchitecture.Application.Queries.Tenants.GetTenantById;
@@ -25,10 +23,7 @@ public sealed class GetTenantByIdQueryHandler :
public async Task Handle(GetTenantByIdQuery request, CancellationToken cancellationToken)
{
- var tenant = _tenantRepository
- .GetAllNoTracking()
- .Include(x => x.Users)
- .FirstOrDefault(x => x.Id == request.TenantId && !x.Deleted);
+ var tenant = await _tenantRepository.GetByIdAsync(request.TenantId);
if (tenant is null)
{
diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
index 18f2df3..7de025a 100644
--- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
@@ -32,6 +32,7 @@ public sealed class GetAllUsersQueryHandler :
{
var usersQuery = _userRepository
.GetAllNoTracking()
+ .IgnoreQueryFilters()
.Where(x => request.IncludeDeleted || !x.Deleted);
if (!string.IsNullOrWhiteSpace(request.SearchTerm))
diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
index f0f2b77..d80268a 100644
--- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
@@ -1,5 +1,4 @@
-using System.Linq;
-using System.Threading;
+using System.Threading;
using System.Threading.Tasks;
using CleanArchitecture.Application.ViewModels.Users;
using CleanArchitecture.Domain.Errors;
@@ -24,9 +23,7 @@ public sealed class GetUserByIdQueryHandler :
public async Task Handle(GetUserByIdQuery request, CancellationToken cancellationToken)
{
- var user = _userRepository
- .GetAllNoTracking()
- .FirstOrDefault(x => x.Id == request.UserId && !x.Deleted);
+ var user = await _userRepository.GetByIdAsync(request.UserId);
if (user is null)
{
diff --git a/CleanArchitecture.Application/gRPC/TenantsApiImplementation.cs b/CleanArchitecture.Application/gRPC/TenantsApiImplementation.cs
index 414206c..97679ac 100644
--- a/CleanArchitecture.Application/gRPC/TenantsApiImplementation.cs
+++ b/CleanArchitecture.Application/gRPC/TenantsApiImplementation.cs
@@ -34,6 +34,7 @@ public sealed class TenantsApiImplementation : TenantsApi.TenantsApiBase
var tenants = await _tenantRepository
.GetAllNoTracking()
+ .IgnoreQueryFilters()
.Where(tenant => idsAsGuids.Contains(tenant.Id))
.Select(tenant => new Tenant
{
diff --git a/CleanArchitecture.Application/gRPC/UsersApiImplementation.cs b/CleanArchitecture.Application/gRPC/UsersApiImplementation.cs
index ff872e1..6255920 100644
--- a/CleanArchitecture.Application/gRPC/UsersApiImplementation.cs
+++ b/CleanArchitecture.Application/gRPC/UsersApiImplementation.cs
@@ -34,6 +34,7 @@ public sealed class UsersApiImplementation : UsersApi.UsersApiBase
var users = await _userRepository
.GetAllNoTracking()
+ .IgnoreQueryFilters()
.Where(user => idsAsGuids.Contains(user.Id))
.Select(user => new GrpcUser
{
diff --git a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
index e1ae055..5f03e8c 100644
--- a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
+++ b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
@@ -8,12 +8,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,7 +24,7 @@
-
+
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/CreateTenant/CreateTenantCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/CreateTenant/CreateTenantCommandHandlerTests.cs
index 0ac8c00..b44cb19 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/CreateTenant/CreateTenantCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/CreateTenant/CreateTenantCommandHandlerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Tenants.CreateTenant;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Shared.Events.Tenant;
@@ -11,13 +12,13 @@ public sealed class CreateTenantCommandHandlerTests
private readonly CreateTenantCommandTestFixture _fixture = new();
[Fact]
- public void Should_Create_Tenant()
+ public async Task Should_Create_Tenant()
{
var command = new CreateTenantCommand(
Guid.NewGuid(),
"Test Tenant");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoDomainNotification()
@@ -28,7 +29,7 @@ public sealed class CreateTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_Tenant_Insufficient_Permissions()
+ public async Task Should_Not_Create_Tenant_Insufficient_Permissions()
{
_fixture.SetupUser();
@@ -36,7 +37,7 @@ public sealed class CreateTenantCommandHandlerTests
Guid.NewGuid(),
"Test Tenant");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -48,7 +49,7 @@ public sealed class CreateTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_Tenant_Already_Exists()
+ public async Task Should_Not_Create_Tenant_Already_Exists()
{
var command = new CreateTenantCommand(
Guid.NewGuid(),
@@ -56,7 +57,7 @@ public sealed class CreateTenantCommandHandlerTests
_fixture.SetupExistingTenant(command.AggregateId);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/DeleteTenant/DeleteTenantCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/DeleteTenant/DeleteTenantCommandHandlerTests.cs
index 68134d9..b3e5579 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/DeleteTenant/DeleteTenantCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/DeleteTenant/DeleteTenantCommandHandlerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Tenants.DeleteTenant;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Shared.Events.Tenant;
@@ -11,13 +12,13 @@ public sealed class DeleteTenantCommandHandlerTests
private readonly DeleteTenantCommandTestFixture _fixture = new();
[Fact]
- public void Should_Delete_Tenant()
+ public async Task Should_Delete_Tenant()
{
var tenant = _fixture.SetupTenant();
var command = new DeleteTenantCommand(tenant.Id);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoDomainNotification()
@@ -26,13 +27,13 @@ public sealed class DeleteTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Delete_Non_Existing_Tenant()
+ public async Task Should_Not_Delete_Non_Existing_Tenant()
{
_fixture.SetupTenant();
var command = new DeleteTenantCommand(Guid.NewGuid());
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -44,14 +45,14 @@ public sealed class DeleteTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Delete_Tenant_Insufficient_Permissions()
+ public async Task Should_Not_Delete_Tenant_Insufficient_Permissions()
{
var tenant = _fixture.SetupTenant();
_fixture.SetupUser();
var command = new DeleteTenantCommand(tenant.Id);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/UpdateTenant/UpdateTenantCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/UpdateTenant/UpdateTenantCommandHandlerTests.cs
index 980b97b..e03eee0 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/UpdateTenant/UpdateTenantCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/Tenant/UpdateTenant/UpdateTenantCommandHandlerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Tenants.UpdateTenant;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Shared.Events.Tenant;
@@ -11,7 +12,7 @@ public sealed class UpdateTenantCommandHandlerTests
private readonly UpdateTenantCommandTestFixture _fixture = new();
[Fact]
- public void Should_Update_Tenant()
+ public async Task Should_Update_Tenant()
{
var command = new UpdateTenantCommand(
Guid.NewGuid(),
@@ -19,7 +20,7 @@ public sealed class UpdateTenantCommandHandlerTests
_fixture.SetupExistingTenant(command.AggregateId);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyCommit()
@@ -30,7 +31,7 @@ public sealed class UpdateTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Update_Tenant_Insufficient_Permissions()
+ public async Task Should_Not_Update_Tenant_Insufficient_Permissions()
{
var command = new UpdateTenantCommand(
Guid.NewGuid(),
@@ -38,7 +39,7 @@ public sealed class UpdateTenantCommandHandlerTests
_fixture.SetupUser();
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -50,13 +51,13 @@ public sealed class UpdateTenantCommandHandlerTests
}
[Fact]
- public void Should_Not_Update_Tenant_Not_Existing()
+ public async Task Should_Not_Update_Tenant_Not_Existing()
{
var command = new UpdateTenantCommand(
Guid.NewGuid(),
"Tenant Name");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
index ef81bc5..25108ee 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Users.CreateUser;
using CleanArchitecture.Domain.Enums;
using CleanArchitecture.Domain.Errors;
@@ -13,7 +14,7 @@ public sealed class CreateUserCommandHandlerTests
private readonly CreateUserCommandTestFixture _fixture = new();
[Fact]
- public void Should_Create_User()
+ public async Task Should_Create_User()
{
_fixture.SetupCurrentUser();
@@ -28,7 +29,7 @@ public sealed class CreateUserCommandHandlerTests
"Email",
"Po=PF]PC6t.?8?ks)A6W");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoDomainNotification()
@@ -37,7 +38,7 @@ public sealed class CreateUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_Already_Existing_User()
+ public async Task Should_Not_Create_Already_Existing_User()
{
_fixture.SetupCurrentUser();
@@ -51,7 +52,7 @@ public sealed class CreateUserCommandHandlerTests
"Email",
"Po=PF]PC6t.?8?ks)A6W");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -63,7 +64,7 @@ public sealed class CreateUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_Already_Existing_Email()
+ public async Task Should_Not_Create_Already_Existing_Email()
{
_fixture.SetupCurrentUser();
@@ -86,7 +87,7 @@ public sealed class CreateUserCommandHandlerTests
"Email",
"Po=PF]PC6t.?8?ks)A6W");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -98,7 +99,7 @@ public sealed class CreateUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_User_Tenant_Does_Not_Exist()
+ public async Task Should_Not_Create_User_Tenant_Does_Not_Exist()
{
_fixture.SetupCurrentUser();
@@ -112,7 +113,7 @@ public sealed class CreateUserCommandHandlerTests
"Email",
"Po=PF]PC6t.?8?ks)A6W");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -124,7 +125,7 @@ public sealed class CreateUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Create_User_Insufficient_Permissions()
+ public async Task Should_Not_Create_User_Insufficient_Permissions()
{
_fixture.SetupUser();
@@ -136,7 +137,7 @@ public sealed class CreateUserCommandHandlerTests
"Email",
"Po=PF]PC6t.?8?ks)A6W");
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
index 7dc1c8d..c61ddb6 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Users.DeleteUser;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Shared.Events.User;
@@ -11,13 +12,13 @@ public sealed class DeleteUserCommandHandlerTests
private readonly DeleteUserCommandTestFixture _fixture = new();
[Fact]
- public void Should_Delete_User()
+ public async Task Should_Delete_User()
{
var user = _fixture.SetupUser();
var command = new DeleteUserCommand(user.Id);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoDomainNotification()
@@ -26,13 +27,13 @@ public sealed class DeleteUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Delete_Non_Existing_User()
+ public async Task Should_Not_Delete_Non_Existing_User()
{
_fixture.SetupUser();
var command = new DeleteUserCommand(Guid.NewGuid());
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
@@ -44,7 +45,7 @@ public sealed class DeleteUserCommandHandlerTests
}
[Fact]
- public void Should_Not_Delete_User_Insufficient_Permissions()
+ public async Task Should_Not_Delete_User_Insufficient_Permissions()
{
var user = _fixture.SetupUser();
@@ -52,7 +53,7 @@ public sealed class DeleteUserCommandHandlerTests
var command = new DeleteUserCommand(user.Id);
- _fixture.CommandHandler.Handle(command, default).Wait();
+ await _fixture.CommandHandler.Handle(command, default);
_fixture
.VerifyNoCommit()
diff --git a/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj b/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
index 1a8efa5..0a38606 100644
--- a/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
+++ b/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
@@ -6,20 +6,20 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
diff --git a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
index 2a72fae..118a211 100644
--- a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
@@ -20,7 +20,7 @@ namespace CleanArchitecture.Domain.Commands.Users.LoginUser;
public sealed class LoginUserCommandHandler : CommandHandlerBase,
IRequestHandler
{
- private const double _expiryDurationMinutes = 30;
+ private const double _expiryDurationMinutes = 60;
private readonly TokenSettings _tokenSettings;
private readonly IUserRepository _userRepository;
diff --git a/CleanArchitecture.Domain/Rabbitmq/RabbitMqHandler.cs b/CleanArchitecture.Domain/Rabbitmq/RabbitMqHandler.cs
index 81cb7bc..43732ab 100644
--- a/CleanArchitecture.Domain/Rabbitmq/RabbitMqHandler.cs
+++ b/CleanArchitecture.Domain/Rabbitmq/RabbitMqHandler.cs
@@ -52,7 +52,8 @@ public sealed class RabbitMqHandler : BackgroundService
{
if (!_configuration.Enabled)
{
- _logger.LogInformation("RabbitMQ is disabled. Skipping the creation of exchange {exchangeName}.", exchangeName);
+ _logger.LogInformation("RabbitMQ is disabled. Skipping the creation of exchange {exchangeName}.",
+ exchangeName);
return;
}
diff --git a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
index c2b987a..36d4546 100644
--- a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
+++ b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
@@ -8,11 +8,11 @@
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -23,7 +23,7 @@
-
+
diff --git a/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj b/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
index 7bc9f1b..a20637f 100644
--- a/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
+++ b/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
@@ -6,20 +6,20 @@
-
-
+
+
-
-
-
-
-
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs b/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
index 6a5517f..1b8258a 100644
--- a/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
+++ b/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
@@ -1,10 +1,11 @@
+using System.Linq;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Infrastructure.Configurations;
using Microsoft.EntityFrameworkCore;
namespace CleanArchitecture.Infrastructure.Database;
-public class ApplicationDbContext : DbContext
+public partial class ApplicationDbContext : DbContext
{
public DbSet Users { get; set; } = null!;
public DbSet Tenants { get; set; } = null!;
@@ -14,6 +15,29 @@ public class ApplicationDbContext : DbContext
}
protected override void OnModelCreating(ModelBuilder builder)
+ {
+ foreach (var entity in builder.Model.GetEntityTypes())
+ {
+ if (entity.ClrType.GetProperty(DbContextUtility.IsDeletedProperty) is not null)
+ {
+ builder.Entity(entity.ClrType)
+ .HasQueryFilter(DbContextUtility.GetIsDeletedRestriction(entity.ClrType));
+ }
+ }
+
+ base.OnModelCreating(builder);
+
+ ApplyConfigurations(builder);
+
+ // Make referential delete behaviour restrict instead of cascade for everything
+ foreach (var relationship in builder.Model.GetEntityTypes()
+ .SelectMany(x => x.GetForeignKeys()))
+ {
+ relationship.DeleteBehavior = DeleteBehavior.Restrict;
+ }
+ }
+
+ private static void ApplyConfigurations(ModelBuilder builder)
{
builder.ApplyConfiguration(new UserConfiguration());
builder.ApplyConfiguration(new TenantConfiguration());
diff --git a/CleanArchitecture.Infrastructure/Database/DbContextUtility.cs b/CleanArchitecture.Infrastructure/Database/DbContextUtility.cs
new file mode 100644
index 0000000..29900c4
--- /dev/null
+++ b/CleanArchitecture.Infrastructure/Database/DbContextUtility.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Linq.Expressions;
+using System.Reflection;
+using Microsoft.EntityFrameworkCore;
+
+namespace CleanArchitecture.Infrastructure.Database;
+
+public partial class ApplicationDbContext
+{
+ public static class DbContextUtility
+ {
+ public const string IsDeletedProperty = "Deleted";
+
+ public static readonly MethodInfo PropertyMethod = typeof(EF)
+ .GetMethod(nameof(EF.Property), BindingFlags.Static | BindingFlags.Public)
+ !.MakeGenericMethod(typeof(bool));
+
+ public static LambdaExpression GetIsDeletedRestriction(Type type)
+ {
+ var parm = Expression.Parameter(type, "it");
+ var prop = Expression.Call(PropertyMethod, parm, Expression.Constant(IsDeletedProperty));
+ var condition = Expression.MakeBinary(ExpressionType.Equal, prop, Expression.Constant(false));
+ var lambda = Expression.Lambda(condition, parm);
+ return lambda;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.Designer.cs b/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.Designer.cs
new file mode 100644
index 0000000..356344d
--- /dev/null
+++ b/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.Designer.cs
@@ -0,0 +1,138 @@
+//
+using System;
+using CleanArchitecture.Infrastructure.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace CleanArchitecture.Infrastructure.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20231001125849_DeletedQueryFilter")]
+ partial class DeletedQueryFilter
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.11")
+ .HasAnnotation("Proxies:ChangeTracking", false)
+ .HasAnnotation("Proxies:CheckEquality", false)
+ .HasAnnotation("Proxies:LazyLoading", true)
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Deleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Tenants");
+
+ b.HasData(
+ new
+ {
+ Id = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a"),
+ Deleted = false,
+ Name = "Admin Tenant"
+ });
+ });
+
+ modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Deleted")
+ .HasColumnType("bit");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(320)
+ .HasColumnType("nvarchar(320)");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("LastLoggedinDate")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("Password")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Role")
+ .HasColumnType("int");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId");
+
+ b.ToTable("Users");
+
+ b.HasData(
+ new
+ {
+ Id = new Guid("7e3892c0-9374-49fa-a3fd-53db637a40ae"),
+ Deleted = false,
+ Email = "admin@email.com",
+ FirstName = "Admin",
+ LastName = "User",
+ Password = "$2a$12$Blal/uiFIJdYsCLTMUik/egLbfg3XhbnxBC6Sb5IKz2ZYhiU/MzL2",
+ Role = 0,
+ Status = 0,
+ TenantId = new Guid("b542bf25-134c-47a2-a0df-84ed14d03c4a")
+ });
+ });
+
+ modelBuilder.Entity("CleanArchitecture.Domain.Entities.User", b =>
+ {
+ b.HasOne("CleanArchitecture.Domain.Entities.Tenant", "Tenant")
+ .WithMany("Users")
+ .HasForeignKey("TenantId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Tenant");
+ });
+
+ modelBuilder.Entity("CleanArchitecture.Domain.Entities.Tenant", b =>
+ {
+ b.Navigation("Users");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.cs b/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.cs
new file mode 100644
index 0000000..752b0af
--- /dev/null
+++ b/CleanArchitecture.Infrastructure/Migrations/20231001125849_DeletedQueryFilter.cs
@@ -0,0 +1,42 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace CleanArchitecture.Infrastructure.Migrations
+{
+ ///
+ public partial class DeletedQueryFilter : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Users_Tenants_TenantId",
+ table: "Users");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Users_Tenants_TenantId",
+ table: "Users",
+ column: "TenantId",
+ principalTable: "Tenants",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Users_Tenants_TenantId",
+ table: "Users");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Users_Tenants_TenantId",
+ table: "Users",
+ column: "TenantId",
+ principalTable: "Tenants",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ }
+ }
+}
diff --git a/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs b/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
index 831c467..cdbe611 100644
--- a/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
+++ b/CleanArchitecture.Infrastructure/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -17,7 +17,7 @@ namespace CleanArchitecture.Infrastructure.Migrations
{
#pragma warning disable 612, 618
modelBuilder
- .HasAnnotation("ProductVersion", "7.0.10")
+ .HasAnnotation("ProductVersion", "7.0.11")
.HasAnnotation("Proxies:ChangeTracking", false)
.HasAnnotation("Proxies:CheckEquality", false)
.HasAnnotation("Proxies:LazyLoading", true)
@@ -119,7 +119,7 @@ namespace CleanArchitecture.Infrastructure.Migrations
b.HasOne("CleanArchitecture.Domain.Entities.Tenant", "Tenant")
.WithMany("Users")
.HasForeignKey("TenantId")
- .OnDelete(DeleteBehavior.Cascade)
+ .OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Tenant");
diff --git a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
index 20da691..f53a280 100644
--- a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
+++ b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
@@ -8,15 +8,15 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs
index d765819..5b5abfd 100644
--- a/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs
+++ b/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs
@@ -37,6 +37,8 @@ public sealed class TenantControllerTests : IClassFixture
message!.Data!.Id.Should().Be(_fixture.CreatedTenantId);
message.Data.Name.Should().Be("Test Tenant");
+
+ message.Data.Users.Count().Should().Be(1);
}
[Fact]
@@ -55,6 +57,10 @@ public sealed class TenantControllerTests : IClassFixture
message.Data!.Items
.FirstOrDefault(x => x.Id == _fixture.CreatedTenantId)
.Should().NotBeNull();
+
+ message.Data.Items
+ .FirstOrDefault(x => x.Id == _fixture.CreatedTenantId)!
+ .Users.Count().Should().Be(1);
}
[Fact]
diff --git a/CleanArchitecture.IntegrationTests/Fixtures/TenantTestFixture.cs b/CleanArchitecture.IntegrationTests/Fixtures/TenantTestFixture.cs
index 3d66346..0d9a821 100644
--- a/CleanArchitecture.IntegrationTests/Fixtures/TenantTestFixture.cs
+++ b/CleanArchitecture.IntegrationTests/Fixtures/TenantTestFixture.cs
@@ -1,5 +1,6 @@
using System;
using CleanArchitecture.Domain.Entities;
+using CleanArchitecture.Domain.Enums;
using CleanArchitecture.Infrastructure.Database;
namespace CleanArchitecture.IntegrationTests.Fixtures;
@@ -16,6 +17,15 @@ public sealed class TenantTestFixture : TestFixtureBase
CreatedTenantId,
"Test Tenant"));
+ context.Users.Add(new User(
+ Guid.NewGuid(),
+ CreatedTenantId,
+ "test@user.de",
+ "test",
+ "user",
+ "Test User",
+ UserRole.User));
+
context.SaveChanges();
}
}
\ No newline at end of file
diff --git a/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
index 2a17507..b89928d 100644
--- a/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
+++ b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
@@ -6,16 +6,16 @@
-
-
-
-
+
+
+
+
-
-
-
+
+
+
diff --git a/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
index 710ccb2..5f363a3 100644
--- a/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
+++ b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
@@ -8,12 +8,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,9 +24,9 @@
-
-
-
+
+
+
diff --git a/Readme.md b/Readme.md
index a2775a8..d2c35c5 100644
--- a/Readme.md
+++ b/Readme.md
@@ -57,15 +57,13 @@ Running the container
### Using docker-compose
-1. Change the ConnectionString in the appsettings.json to `Server=db;Database=clean-architecture;Trusted_Connection=False;MultipleActiveResultSets=true;TrustServerCertificate=True;User Id=SA;Password=Password123!#`
-2. Build the Dockerfile: `docker build -t clean-architecture .`
-3. Running the docker compose: `docker-compose up -d` (Delete: `docker-compose down`)
+1. Build the Dockerfile: `docker build -t clean-architecture .`
+2. Running the docker compose: `docker-compose up -d` (Delete: `docker-compose down`)
### Using Kubernetes
-1. Change the ConnectionString in the appsettings.json to `Server=sql-server;Database=clean-architecture;Trusted_Connection=False;MultipleActiveResultSets=true;TrustServerCertificate=True;User Id=SA;Password=Password123!#`
-2. Build the docker image and push it to the docker hub (Change the image name in the `k8s-deployment.yml` to your own)
-Apply the deployment file: `kubectl apply -f k8s-deployment.yml` (Delete: `kubectl delete -f k8s-deployment.yml`)
+1. Build the docker image and push it to the docker hub (Change the image name in the `k8s-deployment.yml` to your own)
+2. Apply the deployment file: `kubectl apply -f k8s-deployment.yml` (Delete: `kubectl delete -f k8s-deployment.yml`)
## Running the Tests
diff --git a/docker-compose.yml b/docker-compose.yml
index 9bafb9c..5ad1a77 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,6 +13,8 @@ services:
condition: service_healthy
links:
- db
+ environment:
+ - ConnectionStrings__DefaultConnection=Server=db;Database=clean-architecture;Trusted_Connection=False;MultipleActiveResultSets=true;TrustServerCertificate=True;User Id=SA;Password=Password123!#
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost/healthz"]
interval: 30s
diff --git a/k8s-deployments/clean-architecture.yml b/k8s-deployments/clean-architecture.yml
index 86140d1..bfdbfba 100644
--- a/k8s-deployments/clean-architecture.yml
+++ b/k8s-deployments/clean-architecture.yml
@@ -31,4 +31,7 @@ spec:
# Replace this with the path to your built image
image: alexdev28/clean-architecture:latest
ports:
- - containerPort: 80
\ No newline at end of file
+ - containerPort: 80
+ env:
+ - name: ConnectionStrings__DefaultConnection
+ value: Server=sql-server;Database=clean-architecture;Trusted_Connection=False;MultipleActiveResultSets=true;TrustServerCertificate=True;User Id=SA;Password=Password123!#
\ No newline at end of file