diff --git a/CleanArchitecture.Api/CleanArchitecture.Api.csproj b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
index 749f190..6d798e4 100644
--- a/CleanArchitecture.Api/CleanArchitecture.Api.csproj
+++ b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
@@ -24,6 +24,7 @@
+
diff --git a/CleanArchitecture.Api/Controllers/ApiController.cs b/CleanArchitecture.Api/Controllers/ApiController.cs
index d30048e..ddb8cd0 100644
--- a/CleanArchitecture.Api/Controllers/ApiController.cs
+++ b/CleanArchitecture.Api/Controllers/ApiController.cs
@@ -56,7 +56,7 @@ public class ApiController : ControllerBase
return GetErrorStatusCode();
}
- protected HttpStatusCode GetErrorStatusCode()
+ private HttpStatusCode GetErrorStatusCode()
{
if (_notifications.GetNotifications().Any(n => n.Code == ErrorCodes.ObjectNotFound))
{
diff --git a/CleanArchitecture.Api/Controllers/UserController.cs b/CleanArchitecture.Api/Controllers/UserController.cs
index a31a158..5d6cfc6 100644
--- a/CleanArchitecture.Api/Controllers/UserController.cs
+++ b/CleanArchitecture.Api/Controllers/UserController.cs
@@ -29,9 +29,11 @@ public class UserController : ApiController
}
[HttpGet("{id}")]
- public async Task GetUserByIdAsync([FromRoute] Guid id)
+ public async Task GetUserByIdAsync(
+ [FromRoute] Guid id,
+ [FromQuery] bool isDeleted = false)
{
- var user = await _userService.GetUserByUserIdAsync(id);
+ var user = await _userService.GetUserByUserIdAsync(id, isDeleted);
return Response(user);
}
diff --git a/CleanArchitecture.Api/Program.cs b/CleanArchitecture.Api/Program.cs
index db6a81b..4aee2bc 100644
--- a/CleanArchitecture.Api/Program.cs
+++ b/CleanArchitecture.Api/Program.cs
@@ -1,5 +1,6 @@
using CleanArchitecture.Application.Extensions;
using CleanArchitecture.Domain.Extensions;
+using CleanArchitecture.gRPC;
using CleanArchitecture.Infrastructure.Database;
using CleanArchitecture.Infrastructure.Extensions;
using Microsoft.AspNetCore.Builder;
@@ -10,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
+builder.Services.AddGrpc();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
@@ -43,6 +45,7 @@ app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
+app.MapGrpcService();
using (IServiceScope scope = app.Services.CreateScope())
{
diff --git a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
index 129ebce..f93ebb1 100644
--- a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
+++ b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
@@ -2,7 +2,6 @@
net7.0
- enable
enable
false
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
index ef02fbf..3357845 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Linq;
using CleanArchitecture.Application.Queries.Users.GetAll;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Domain.Interfaces.Repositories;
@@ -8,7 +10,7 @@ namespace CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture
{
- public Mock UserRepository { get; }
+ private Mock UserRepository { get; }
public GetAllUsersQueryHandler Handler { get; }
public Guid ExistingUserId { get; } = Guid.NewGuid();
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
index 0671991..d50699f 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Linq;
using CleanArchitecture.Application.Queries.Users.GetUserById;
using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Domain.Interfaces.Repositories;
@@ -8,7 +10,7 @@ namespace CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
public sealed class GetUserByIdTestFixture : QueryHandlerBaseFixture
{
- public Mock UserRepository { get; }
+ private Mock UserRepository { get; }
public GetUserByIdQueryHandler Handler { get; }
public Guid ExistingUserId { get; } = Guid.NewGuid();
diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
index a625aa0..44af10e 100644
--- a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
+++ b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
@@ -1,3 +1,5 @@
+using System.Linq;
+using System.Threading.Tasks;
using CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
using FluentAssertions;
using Xunit;
@@ -18,7 +20,7 @@ public sealed class GetAllUsersQueryHandlerTests
default);
_fixture.VerifyNoDomainNotification();
-
+
result.Should().NotBeNull();
result.Should().ContainSingle();
result.FirstOrDefault()!.Id.Should().Be(_fixture.ExistingUserId);
diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
index f24ece9..b4fa2bd 100644
--- a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
+++ b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Threading.Tasks;
using CleanArchitecture.Application.Queries.Users.GetUserById;
using CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
using CleanArchitecture.Domain.Errors;
@@ -16,7 +18,7 @@ public sealed class GetUserByIdQueryHandlerTests
_fixture.SetupUserAsync();
var result = await _fixture.Handler.Handle(
- new(_fixture.ExistingUserId),
+ new(_fixture.ExistingUserId, false),
default);
_fixture.VerifyNoDomainNotification();
@@ -30,7 +32,7 @@ public sealed class GetUserByIdQueryHandlerTests
{
_fixture.SetupUserAsync();
- var request = new GetUserByIdQuery(Guid.NewGuid());
+ var request = new GetUserByIdQuery(Guid.NewGuid(), false);
var result = await _fixture.Handler.Handle(
request,
default);
diff --git a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
index 752e40e..beaec9f 100644
--- a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
+++ b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
@@ -3,7 +3,6 @@ using CleanArchitecture.Application.Interfaces;
using CleanArchitecture.Application.Queries.Users.GetAll;
using CleanArchitecture.Application.Queries.Users.GetUserById;
using CleanArchitecture.Application.Services;
-using CleanArchitecture.Application.ViewModels;
using CleanArchitecture.Application.ViewModels.Users;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
diff --git a/CleanArchitecture.Application/Interfaces/IUserService.cs b/CleanArchitecture.Application/Interfaces/IUserService.cs
index 650a50f..5f65254 100644
--- a/CleanArchitecture.Application/Interfaces/IUserService.cs
+++ b/CleanArchitecture.Application/Interfaces/IUserService.cs
@@ -7,7 +7,7 @@ namespace CleanArchitecture.Application.Interfaces;
public interface IUserService
{
- public Task GetUserByUserIdAsync(Guid userId);
+ public Task GetUserByUserIdAsync(Guid userId, bool isDeleted);
public Task> GetAllUsersAsync();
public Task CreateUserAsync(CreateUserViewModel user);
public Task UpdateUserAsync(UpdateUserViewModel user);
diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
index 76e942c..40e8571 100644
--- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
@@ -1,8 +1,7 @@
using System.Collections.Generic;
-using CleanArchitecture.Application.ViewModels;
using CleanArchitecture.Application.ViewModels.Users;
using MediatR;
namespace CleanArchitecture.Application.Queries.Users.GetAll;
-public sealed record GetAllUsersQuery() : IRequest>;
+public sealed record GetAllUsersQuery : IRequest>;
diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
index bcb4aad..c43bad2 100644
--- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs
@@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using CleanArchitecture.Application.ViewModels;
using CleanArchitecture.Application.ViewModels.Users;
using CleanArchitecture.Domain.Interfaces.Repositories;
using MediatR;
diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
index 115a31a..e394336 100644
--- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
@@ -1,8 +1,7 @@
using System;
-using CleanArchitecture.Application.ViewModels;
using CleanArchitecture.Application.ViewModels.Users;
using MediatR;
namespace CleanArchitecture.Application.Queries.Users.GetUserById;
-public sealed record GetUserByIdQuery(Guid UserId) : IRequest;
+public sealed record GetUserByIdQuery(Guid UserId, bool IsDeleted) : IRequest;
diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
index 1109d00..2c166a8 100644
--- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
@@ -1,7 +1,6 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using CleanArchitecture.Application.ViewModels;
using CleanArchitecture.Application.ViewModels.Users;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Domain.Interfaces;
@@ -27,7 +26,9 @@ public sealed class GetUserByIdQueryHandler :
{
var user = _userRepository
.GetAllNoTracking()
- .FirstOrDefault(x => x.Id == request.UserId && !x.Deleted);
+ .FirstOrDefault(x =>
+ x.Id == request.UserId &&
+ x.Deleted == request.IsDeleted);
if (user == null)
{
diff --git a/CleanArchitecture.Application/Services/UserService.cs b/CleanArchitecture.Application/Services/UserService.cs
index bd99d42..dd91d4f 100644
--- a/CleanArchitecture.Application/Services/UserService.cs
+++ b/CleanArchitecture.Application/Services/UserService.cs
@@ -21,9 +21,9 @@ public sealed class UserService : IUserService
_bus = bus;
}
- public async Task GetUserByUserIdAsync(Guid userId)
+ public async Task GetUserByUserIdAsync(Guid userId, bool isDeleted)
{
- return await _bus.QueryAsync(new GetUserByIdQuery(userId));
+ return await _bus.QueryAsync(new GetUserByIdQuery(userId, isDeleted));
}
public async Task> GetAllUsersAsync()
diff --git a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
index 7ae8e02..3745ee4 100644
--- a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
+++ b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
@@ -2,7 +2,6 @@
net7.0
- enable
enable
false
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
index 6cf2b53..7d5109f 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.CreateUser;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Domain.Events.User;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
index 50a82da..2f30515 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.CreateUser;
using CleanArchitecture.Domain.Interfaces.Repositories;
using Moq;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
index 60fd654..a6c54e4 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.CreateUser;
using CleanArchitecture.Domain.Errors;
using Xunit;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
index ef70639..dc23bd6 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.DeleteUser;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Domain.Events.User;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
index 9da0eee..19f7761 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.DeleteUser;
using CleanArchitecture.Domain.Interfaces.Repositories;
using Moq;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
index 2c70984..50106e5 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.DeleteUser;
using CleanArchitecture.Domain.Errors;
using Xunit;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
index 182f9ed..bdd53e6 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Users.UpdateUser;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Domain.Events.User;
@@ -31,7 +33,7 @@ public sealed class UpdateUserCommandHandlerTests
[Fact]
public async Task Should_Not_Update_Non_Existing_User()
{
- var user = _fixture.SetupUser();
+ _fixture.SetupUser();
var command = new UpdateUserCommand(
Guid.NewGuid(),
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
index d3dd415..1b63128 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.UpdateUser;
using CleanArchitecture.Domain.Interfaces.Repositories;
using Moq;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
index 9b06cac..e593959 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
@@ -1,3 +1,4 @@
+using System;
using CleanArchitecture.Domain.Commands.Users.UpdateUser;
using CleanArchitecture.Domain.Errors;
using Xunit;
diff --git a/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs b/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
index ddf2bf7..01964a0 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq.Expressions;
using CleanArchitecture.Domain.Interfaces;
using CleanArchitecture.Domain.Notifications;
@@ -7,9 +8,9 @@ namespace CleanArchitecture.Domain.Tests;
public class CommandHandlerFixtureBase
{
- public Mock Bus { get; protected set; }
- public Mock UnitOfWork { get; protected set; }
- public Mock NotificationHandler { get; protected set; }
+ protected Mock Bus { get; }
+ protected Mock UnitOfWork { get; }
+ protected Mock NotificationHandler { get; }
protected CommandHandlerFixtureBase()
{
diff --git a/CleanArchitecture.Domain.Tests/ValidationTestBase.cs b/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
index a039d3d..7f985c8 100644
--- a/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
+++ b/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
@@ -1,3 +1,5 @@
+using System.Collections.Generic;
+using System.Linq;
using CleanArchitecture.Domain.Commands;
using FluentAssertions;
using FluentValidation;
@@ -8,7 +10,7 @@ public class ValidationTestBase
where TCommand : CommandBase
where TValidation: AbstractValidator
{
- protected readonly TValidation _validation;
+ private readonly TValidation _validation;
protected ValidationTestBase(TValidation validation)
{
diff --git a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
index 3762540..6106289 100644
--- a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
@@ -4,7 +4,7 @@ namespace CleanArchitecture.Domain.Commands.Users.CreateUser;
public sealed class CreateUserCommand : CommandBase
{
- private static readonly CreateUserCommandValidation _validation = new();
+ private readonly CreateUserCommandValidation _validation = new();
public Guid UserId { get; }
public string Email { get; }
diff --git a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
index 34277b1..a15d7d6 100644
--- a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
@@ -4,7 +4,7 @@ namespace CleanArchitecture.Domain.Commands.Users.DeleteUser;
public sealed class DeleteUserCommand : CommandBase
{
- private static readonly DeleteUserCommandValidation _validation = new();
+ private readonly DeleteUserCommandValidation _validation = new();
public Guid UserId { get; }
diff --git a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
index 1097e66..257e4ac 100644
--- a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
+++ b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
@@ -2,7 +2,6 @@
net7.0
- enable
enable
false
diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
index a03f826..95148af 100644
--- a/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
@@ -35,7 +35,7 @@ public sealed class DomainNotificationHandlerTests
var domainNotification = new DomainNotification(key, value, code);
var domainNotificationHandler = new DomainNotificationHandler();
- domainNotificationHandler.Handle(domainNotification, default);
+ domainNotificationHandler.Handle(domainNotification);
domainNotificationHandler.GetNotifications().Should().HaveCount(1);
}
diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
index 913dd4d..d942a92 100644
--- a/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
@@ -1,4 +1,5 @@
-using CleanArchitecture.Domain.Notifications;
+using System;
+using CleanArchitecture.Domain.Notifications;
using FluentAssertions;
using Xunit;
diff --git a/CleanArchitecture.Infrastructure.Tests/InMemoryBusTests.cs b/CleanArchitecture.Infrastructure.Tests/InMemoryBusTests.cs
index 7dc2567..f3ed4d8 100644
--- a/CleanArchitecture.Infrastructure.Tests/InMemoryBusTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/InMemoryBusTests.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
using CleanArchitecture.Domain.Commands.Users.DeleteUser;
using CleanArchitecture.Domain.Events.User;
using CleanArchitecture.Domain.Notifications;
diff --git a/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs b/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
index 32f15da..2a0e51f 100644
--- a/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
using CleanArchitecture.Infrastructure.Database;
using CleanArchitecture.Infrastructure.Tests.Fixtures;
using FluentAssertions;
@@ -37,7 +40,7 @@ public sealed class UnitOfWorkTests
dbContextMock
.Setup(x => x.SaveChangesAsync(CancellationToken.None))
- .Throws(new DbUpdateException("Boom", new System.Exception("it broke")));
+ .Throws(new DbUpdateException("Boom", new Exception("it broke")));
var unitOfWork = UnitOfWorkTestFixture.GetUnitOfWork(dbContextMock.Object, loggerMock.Object);
@@ -59,8 +62,8 @@ public sealed class UnitOfWorkTests
var unitOfWork = UnitOfWorkTestFixture.GetUnitOfWork(dbContextMock.Object, loggerMock.Object);
- Func knalltAction = async () => await unitOfWork.CommitAsync();
+ Func throwsAction = async () => await unitOfWork.CommitAsync();
- await knalltAction.Should().ThrowAsync();
+ await throwsAction.Should().ThrowAsync();
}
}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs b/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
index f18e513..52b768d 100644
--- a/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
+++ b/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
@@ -10,23 +10,23 @@ namespace CleanArchitecture.Infrastructure.Repositories;
public class BaseRepository : IRepository where TEntity : Entity
{
- protected readonly DbContext _dbContext;
- protected readonly DbSet _dbSet;
+ private readonly DbContext _dbContext;
+ protected readonly DbSet DbSet;
- public BaseRepository(DbContext context)
+ protected BaseRepository(DbContext context)
{
_dbContext = context;
- _dbSet = _dbContext.Set();
+ DbSet = _dbContext.Set();
}
public void Add(TEntity entity)
{
- _dbSet.Add(entity);
+ DbSet.Add(entity);
}
public void AddRange(IEnumerable entities)
{
- _dbSet.AddRange(entities);
+ DbSet.AddRange(entities);
}
public void Dispose()
@@ -37,17 +37,17 @@ public class BaseRepository : IRepository where TEntity : Enti
public virtual IQueryable GetAll()
{
- return _dbSet;
+ return DbSet;
}
public virtual IQueryable GetAllNoTracking()
{
- return _dbSet.AsNoTracking();
+ return DbSet.AsNoTracking();
}
public virtual async Task GetByIdAsync(Guid id)
{
- return await _dbSet.FindAsync(id);
+ return await DbSet.FindAsync(id);
}
public int SaveChanges()
@@ -65,24 +65,24 @@ public class BaseRepository : IRepository where TEntity : Enti
public virtual void Update(TEntity entity)
{
- _dbSet.Update(entity);
+ DbSet.Update(entity);
}
public Task ExistsAsync(Guid id)
{
- return _dbSet.AnyAsync(entity => entity.Id == id);
+ return DbSet.AnyAsync(entity => entity.Id == id);
}
public void Remove(TEntity entity, bool hardDelete = false)
{
if (hardDelete)
{
- _dbSet.Remove(entity);
+ DbSet.Remove(entity);
}
else
{
entity.Delete();
- _dbSet.Update(entity);
+ DbSet.Update(entity);
}
}
diff --git a/CleanArchitecture.Infrastructure/Repositories/UserRepository.cs b/CleanArchitecture.Infrastructure/Repositories/UserRepository.cs
index 1fb07a7..19976cf 100644
--- a/CleanArchitecture.Infrastructure/Repositories/UserRepository.cs
+++ b/CleanArchitecture.Infrastructure/Repositories/UserRepository.cs
@@ -14,6 +14,6 @@ public sealed class UserRepository : BaseRepository, IUserRepository
public async Task GetByEmailAsync(string email)
{
- return await _dbSet.SingleOrDefaultAsync(user => user.Email == email);
+ return await DbSet.SingleOrDefaultAsync(user => user.Email == email);
}
}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/UnitOfWork.cs b/CleanArchitecture.Infrastructure/UnitOfWork.cs
index 0525866..97d88a9 100644
--- a/CleanArchitecture.Infrastructure/UnitOfWork.cs
+++ b/CleanArchitecture.Infrastructure/UnitOfWork.cs
@@ -6,7 +6,7 @@ using Microsoft.Extensions.Logging;
namespace CleanArchitecture.Infrastructure;
-public class UnitOfWork : IUnitOfWork where TContext : DbContext
+public sealed class UnitOfWork : IUnitOfWork where TContext : DbContext
{
private readonly TContext _context;
private readonly ILogger> _logger;
@@ -34,10 +34,11 @@ public class UnitOfWork : IUnitOfWork where TContext : DbContext
public void Dispose()
{
Dispose(true);
+ // ReSharper disable once GCSuppressFinalizeForTypeWithoutDestructor
GC.SuppressFinalize(this);
}
- protected virtual void Dispose(bool disposing)
+ private void Dispose(bool disposing)
{
if (disposing)
{
diff --git a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
index 255c2cf..08d7f1f 100644
--- a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
+++ b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
@@ -2,7 +2,6 @@
net7.0
- enable
enable
false
diff --git a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
index de56e73..fd8791b 100644
--- a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
+++ b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
@@ -1,4 +1,8 @@
-using System.Net;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
using CleanArchitecture.Application.ViewModels.Users;
using CleanArchitecture.IntegrationTests.Extensions;
using CleanArchitecture.IntegrationTests.Fixtures;
@@ -8,7 +12,7 @@ using Xunit.Priority;
namespace CleanArchitecture.IntegrationTests.Controller;
-[Collection("Integrationtests")]
+[Collection("IntegrationTests")]
[TestCaseOrderer(PriorityOrderer.Name, PriorityOrderer.Assembly)]
public sealed class UserControllerTests : IClassFixture
{
@@ -122,7 +126,7 @@ public sealed class UserControllerTests : IClassFixture
message?.Data.Should().NotBeNull();
- var content = message!.Data!;
+ var content = message!.Data!.ToList();
content.Should().ContainSingle();
content.First().Id.Should().Be(_fixture.CreatedUserId);
@@ -142,7 +146,7 @@ public sealed class UserControllerTests : IClassFixture
message?.Data.Should().NotBeEmpty();
- var content = message!.Data!;
+ var content = message!.Data;
content.Should().Be(_fixture.CreatedUserId);
}
diff --git a/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
index 7179db1..8cb7fad 100644
--- a/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
+++ b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
@@ -1,4 +1,7 @@
-using System.Data.Common;
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Linq;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
@@ -17,7 +20,7 @@ public static class FunctionalTestsServiceCollectionExtensions
services.AddScoped(p =>
DbContextOptionsFactory(
p,
- (sp, options) => options
+ (_, options) => options
.ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning))
.UseLazyLoadingProxies()
.UseSqlite(connection)));
@@ -35,7 +38,7 @@ public static class FunctionalTestsServiceCollectionExtensions
builder.UseApplicationServiceProvider(applicationServiceProvider);
- optionsAction?.Invoke(applicationServiceProvider, builder);
+ optionsAction.Invoke(applicationServiceProvider, builder);
return builder.Options;
}
diff --git a/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
index 45ace89..f765a9c 100644
--- a/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
+++ b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
@@ -1,12 +1,14 @@
-using System.Text;
+using System.Net.Http;
+using System.Text;
using System.Text.Json;
+using System.Threading.Tasks;
using CleanArchitecture.Api.Models;
namespace CleanArchitecture.IntegrationTests.Extensions;
-public static class HttpExensions
+public static class HttpExtensions
{
- public static JsonSerializerOptions JsonSerializerOptions = new()
+ private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{
PropertyNameCaseInsensitive = true,
};
diff --git a/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
index afaa3d1..2d4994e 100644
--- a/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
+++ b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
@@ -1,4 +1,7 @@
-using CleanArchitecture.Infrastructure.Database;
+using System;
+using System.IO;
+using System.Net.Http;
+using CleanArchitecture.Infrastructure.Database;
using CleanArchitecture.IntegrationTests.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
diff --git a/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
index 24bd329..5d31bea 100644
--- a/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
+++ b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
@@ -1,4 +1,6 @@
-namespace CleanArchitecture.IntegrationTests.Fixtures;
+using System;
+
+namespace CleanArchitecture.IntegrationTests.Fixtures;
public sealed class UserTestFixture : TestFixtureBase
{
diff --git a/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
index 3a1dd7c..0e9f243 100644
--- a/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
+++ b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
@@ -1,4 +1,5 @@
-using CleanArchitecture.Infrastructure.Database;
+using System;
+using CleanArchitecture.Infrastructure.Database;
using CleanArchitecture.Infrastructure.Extensions;
using CleanArchitecture.IntegrationTests.Extensions;
using Microsoft.AspNetCore.Hosting;
diff --git a/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
new file mode 100644
index 0000000..fa76384
--- /dev/null
+++ b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net7.0
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CleanArchitecture.Proto/Users/Models.proto b/CleanArchitecture.Proto/Users/Models.proto
new file mode 100644
index 0000000..b627309
--- /dev/null
+++ b/CleanArchitecture.Proto/Users/Models.proto
@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+option csharp_namespace = "CleanArchitecture.Proto.Users";
+
+message GrpcUser {
+ string id = 1;
+ string firstName = 3;
+ string lastName = 4;
+ string email = 5;
+ bool isDeleted = 6;
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Proto/Users/UsersApi.proto b/CleanArchitecture.Proto/Users/UsersApi.proto
new file mode 100644
index 0000000..557b028
--- /dev/null
+++ b/CleanArchitecture.Proto/Users/UsersApi.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+option csharp_namespace = "CleanArchitecture.Proto.Users";
+
+import "Users/Models.proto";
+
+service UsersApi {
+ rpc GetByIds(GetByIdsRequest) returns (GetByIdsResult);
+}
+
+message GetByIdsResult {
+ repeated GrpcUser users = 1;
+}
+
+message GetByIdsRequest {
+ repeated string ids = 1;
+}
diff --git a/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
new file mode 100644
index 0000000..732fc33
--- /dev/null
+++ b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net7.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
diff --git a/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs b/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs
new file mode 100644
index 0000000..63dd2bf
--- /dev/null
+++ b/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using CleanArchitecture.Domain.Entities;
+using CleanArchitecture.Domain.Interfaces.Repositories;
+using MockQueryable.Moq;
+using Moq;
+
+namespace CleanArchitecture.gRPC.Tests.Fixtures;
+
+public sealed class UserTestsFixture
+{
+ private Mock UserRepository { get; } = new ();
+
+ public UsersApiImplementation UsersApiImplementation { get; }
+
+ public IEnumerable ExistingUsers { get; }
+
+ public UserTestsFixture()
+ {
+ ExistingUsers = new List()
+ {
+ new (Guid.NewGuid(), "test@test.de", "Test First Name", "Test Last Name"),
+ new (Guid.NewGuid(), "email@Email.de", "Email First Name", "Email Last Name"),
+ new (Guid.NewGuid(), "user@user.de", "User First Name", "User Last Name"),
+ };
+
+ var queryable = ExistingUsers.AsQueryable().BuildMock();
+
+ UserRepository
+ .Setup(repository => repository.GetAllNoTracking())
+ .Returns(queryable);
+
+ UsersApiImplementation = new UsersApiImplementation(UserRepository.Object);
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.gRPC.Tests/Users/GetUsersByIdsTests.cs b/CleanArchitecture.gRPC.Tests/Users/GetUsersByIdsTests.cs
new file mode 100644
index 0000000..5a4302b
--- /dev/null
+++ b/CleanArchitecture.gRPC.Tests/Users/GetUsersByIdsTests.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CleanArchitecture.gRPC.Tests.Fixtures;
+using CleanArchitecture.Proto.Users;
+using FluentAssertions;
+using Xunit;
+
+namespace CleanArchitecture.gRPC.Tests.Users;
+
+public sealed class GetUsersByIdsTests : IClassFixture
+{
+ private readonly UserTestsFixture _fixture;
+
+ public GetUsersByIdsTests(UserTestsFixture fixture)
+ {
+ _fixture = fixture;
+ }
+
+ [Fact]
+ public async Task Should_Get_Empty_List_If_No_Ids_Are_Given()
+ {
+ var result = await _fixture.UsersApiImplementation.GetByIds(
+ SetupRequest(Enumerable.Empty()),
+ null!);
+
+ result.Users.Should().HaveCount(0);
+ }
+
+ [Fact]
+ public async Task Should_Get_Requested_Asked_Ids()
+ {
+ var nonExistingId = Guid.NewGuid();
+
+ var ids = _fixture.ExistingUsers
+ .Take(2)
+ .Select(user => user.Id)
+ .ToList();
+
+ ids.Add(nonExistingId);
+
+ var result = await _fixture.UsersApiImplementation.GetByIds(
+ SetupRequest(ids),
+ null!);
+
+ result.Users.Should().HaveCount(2);
+
+ foreach (var user in result.Users)
+ {
+ var userId = Guid.Parse(user.Id);
+
+ userId.Should().NotBe(nonExistingId);
+
+ var mockUser = _fixture.ExistingUsers.First(u => u.Id == userId);
+
+ mockUser.Should().NotBeNull();
+
+ user.Email.Should().Be(mockUser.Email);
+ user.FirstName.Should().Be(mockUser.GivenName);
+ user.LastName.Should().Be(mockUser.Surname);
+ }
+ }
+
+ private static GetByIdsRequest SetupRequest(IEnumerable ids)
+ {
+ var request = new GetByIdsRequest();
+
+ request.Ids.AddRange(ids.Select(id => id.ToString()));
+ request.Ids.Add("Not a guid");
+
+ return request;
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj b/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj
new file mode 100644
index 0000000..65b4b52
--- /dev/null
+++ b/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net7.0
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CleanArchitecture.gRPC/UsersApiImplementation.cs b/CleanArchitecture.gRPC/UsersApiImplementation.cs
new file mode 100644
index 0000000..279bdfc
--- /dev/null
+++ b/CleanArchitecture.gRPC/UsersApiImplementation.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using CleanArchitecture.Domain.Interfaces.Repositories;
+using CleanArchitecture.Proto.Users;
+using Grpc.Core;
+using Microsoft.EntityFrameworkCore;
+
+namespace CleanArchitecture.gRPC;
+
+public sealed class UsersApiImplementation : UsersApi.UsersApiBase
+{
+ private readonly IUserRepository _userRepository;
+
+ public UsersApiImplementation(IUserRepository userRepository)
+ {
+ _userRepository = userRepository;
+ }
+
+ public override async Task GetByIds(
+ GetByIdsRequest request,
+ ServerCallContext context)
+ {
+ var idsAsGuids = new List(request.Ids.Count);
+
+ foreach (var id in request.Ids)
+ {
+ if (Guid.TryParse(id, out var parsed))
+ {
+ idsAsGuids.Add(parsed);
+ }
+ }
+
+ var users = await _userRepository
+ .GetAllNoTracking()
+ .Where(user => idsAsGuids.Contains(user.Id))
+ .Select(user => new GrpcUser
+ {
+ Id = user.Id.ToString(),
+ Email = user.Email,
+ FirstName = user.GivenName,
+ LastName = user.Surname,
+ IsDeleted = user.Deleted
+ })
+ .ToListAsync();
+
+ var result = new GetByIdsResult();
+
+ result.Users.AddRange(users);
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.sln b/CleanArchitecture.sln
index 22483d0..31560fb 100644
--- a/CleanArchitecture.sln
+++ b/CleanArchitecture.sln
@@ -16,6 +16,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanArchitecture.Infrastru
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanArchitecture.IntegrationTests", "CleanArchitecture.IntegrationTests\CleanArchitecture.IntegrationTests.csproj", "{39732BD4-909F-410C-8737-1F9FE3E269A7}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanArchitecture.gRPC", "CleanArchitecture.gRPC\CleanArchitecture.gRPC.csproj", "{7A6353A9-B60C-4B13-A849-D21B315047EE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanArchitecture.Proto", "CleanArchitecture.Proto\CleanArchitecture.Proto.csproj", "{5F978903-7A7A-45C2-ABE0-C2906ECD326B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CleanArchitecture.gRPC.Tests", "CleanArchitecture.gRPC.Tests\CleanArchitecture.gRPC.Tests.csproj", "{E3A836DD-85DB-44FD-BC19-DDFE111D9EB0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -54,5 +60,17 @@ Global
{39732BD4-909F-410C-8737-1F9FE3E269A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39732BD4-909F-410C-8737-1F9FE3E269A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39732BD4-909F-410C-8737-1F9FE3E269A7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7A6353A9-B60C-4B13-A849-D21B315047EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A6353A9-B60C-4B13-A849-D21B315047EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A6353A9-B60C-4B13-A849-D21B315047EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A6353A9-B60C-4B13-A849-D21B315047EE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F978903-7A7A-45C2-ABE0-C2906ECD326B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5F978903-7A7A-45C2-ABE0-C2906ECD326B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F978903-7A7A-45C2-ABE0-C2906ECD326B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5F978903-7A7A-45C2-ABE0-C2906ECD326B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E3A836DD-85DB-44FD-BC19-DDFE111D9EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E3A836DD-85DB-44FD-BC19-DDFE111D9EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E3A836DD-85DB-44FD-BC19-DDFE111D9EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3A836DD-85DB-44FD-BC19-DDFE111D9EB0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/Todo.txt b/Todo.txt
index 4d40328..ebb0118 100644
--- a/Todo.txt
+++ b/Todo.txt
@@ -1,3 +1,4 @@
- Remove warnings and apply suggestions
-- Add gRPC support
- Add authentication and authorization
+- Utility integration tests
+- Queryhandler tests for deleted users
\ No newline at end of file