From 0f978131db3629609cd9e8487ac7ac76ea239ddb Mon Sep 17 00:00:00 2001 From: "Daniel Mackay [SSW]" <2636640+danielmackay@users.noreply.github.com> Date: Mon, 17 Jul 2023 21:58:21 +1000 Subject: [PATCH] Refactored Domain to use a feature based approach --- .../Interfaces/IApplicationDbContext.cs | 2 +- .../CreateTodoItem/CreateTodoItemCommand.cs | 2 +- .../TodoItemCreatedEventHandler.cs | 2 +- .../GetAllTodoItems/GetAllTodoItemsMapping.cs | 2 +- .../Specifications/AllTodoItemSpec.cs | 2 +- .../Specifications/TodoItemByTitleSpec.cs | 2 +- src/Domain/GlobalUsing.cs | 2 - .../{Enum => TodoItems}/PriorityLevel.cs | 2 +- .../{Entities => TodoItems}/TodoItem.cs | 101 +++++++++--------- .../TodoItemCompletedEvent.cs | 3 +- .../TodoItemCreatedEvent.cs | 3 +- .../Persistence/ApplicationDbContext.cs | 2 +- .../ApplicationDbContextInitializer.cs | 5 +- .../Configuration/TodoItemConfiguration.cs | 2 +- .../CreateTodoItemCommandTests.cs | 2 +- .../GetAllTodoItemsQueryTests.cs | 2 +- .../Specifications/AllTodoItemSpecTests.cs | 2 +- .../TodoItemByTitleSpecTests.cs | 2 +- .../Entities/TodoItemTests.cs | 5 +- 19 files changed, 69 insertions(+), 76 deletions(-) delete mode 100644 src/Domain/GlobalUsing.cs rename src/Domain/{Enum => TodoItems}/PriorityLevel.cs (61%) rename src/Domain/{Entities => TodoItems}/TodoItem.cs (90%) rename src/Domain/{Events => TodoItems}/TodoItemCompletedEvent.cs (56%) rename src/Domain/{Events => TodoItems}/TodoItemCreatedEvent.cs (56%) diff --git a/src/Application/Common/Interfaces/IApplicationDbContext.cs b/src/Application/Common/Interfaces/IApplicationDbContext.cs index 764f523b..619f6e94 100644 --- a/src/Application/Common/Interfaces/IApplicationDbContext.cs +++ b/src/Application/Common/Interfaces/IApplicationDbContext.cs @@ -1,5 +1,5 @@ using Microsoft.EntityFrameworkCore; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Common.Interfaces; diff --git a/src/Application/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommand.cs b/src/Application/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommand.cs index 1dea834a..26ce3462 100644 --- a/src/Application/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommand.cs +++ b/src/Application/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommand.cs @@ -1,5 +1,5 @@ using SSW.CleanArchitecture.Application.Common.Interfaces; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Features.TodoItems.Commands.CreateTodoItem; diff --git a/src/Application/Features/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs b/src/Application/Features/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs index 5ff14bad..8b2ddef5 100644 --- a/src/Application/Features/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs +++ b/src/Application/Features/TodoItems/EventHandlers/TodoItemCreatedEventHandler.cs @@ -1,5 +1,5 @@ using Microsoft.Extensions.Logging; -using SSW.CleanArchitecture.Domain.Events; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Features.TodoItems.EventHandlers; diff --git a/src/Application/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsMapping.cs b/src/Application/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsMapping.cs index d9a52c05..7ed92d25 100644 --- a/src/Application/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsMapping.cs +++ b/src/Application/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsMapping.cs @@ -1,4 +1,4 @@ -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Features.TodoItems.Queries.GetAllTodoItems; diff --git a/src/Application/Features/TodoItems/Specifications/AllTodoItemSpec.cs b/src/Application/Features/TodoItems/Specifications/AllTodoItemSpec.cs index 011aa963..535b9120 100644 --- a/src/Application/Features/TodoItems/Specifications/AllTodoItemSpec.cs +++ b/src/Application/Features/TodoItems/Specifications/AllTodoItemSpec.cs @@ -1,5 +1,5 @@ using Ardalis.Specification; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Features.TodoItems.Specifications; diff --git a/src/Application/Features/TodoItems/Specifications/TodoItemByTitleSpec.cs b/src/Application/Features/TodoItems/Specifications/TodoItemByTitleSpec.cs index 325d2bcf..6f933aee 100644 --- a/src/Application/Features/TodoItems/Specifications/TodoItemByTitleSpec.cs +++ b/src/Application/Features/TodoItems/Specifications/TodoItemByTitleSpec.cs @@ -1,5 +1,5 @@ using Ardalis.Specification; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.Features.TodoItems.Specifications; diff --git a/src/Domain/GlobalUsing.cs b/src/Domain/GlobalUsing.cs deleted file mode 100644 index c06b5d4f..00000000 --- a/src/Domain/GlobalUsing.cs +++ /dev/null @@ -1,2 +0,0 @@ -global using SSW.CleanArchitecture.Domain.Common; -global using SSW.CleanArchitecture.Domain.Enum; diff --git a/src/Domain/Enum/PriorityLevel.cs b/src/Domain/TodoItems/PriorityLevel.cs similarity index 61% rename from src/Domain/Enum/PriorityLevel.cs rename to src/Domain/TodoItems/PriorityLevel.cs index 7e27ba02..e01c6d46 100644 --- a/src/Domain/Enum/PriorityLevel.cs +++ b/src/Domain/TodoItems/PriorityLevel.cs @@ -1,4 +1,4 @@ -namespace SSW.CleanArchitecture.Domain.Enum; +namespace SSW.CleanArchitecture.Domain.TodoItems; public enum PriorityLevel { diff --git a/src/Domain/Entities/TodoItem.cs b/src/Domain/TodoItems/TodoItem.cs similarity index 90% rename from src/Domain/Entities/TodoItem.cs rename to src/Domain/TodoItems/TodoItem.cs index 8fd17538..9a9924b4 100644 --- a/src/Domain/Entities/TodoItem.cs +++ b/src/Domain/TodoItems/TodoItem.cs @@ -1,52 +1,51 @@ -using SSW.CleanArchitecture.Domain.Common.Base; -using SSW.CleanArchitecture.Domain.Events; - -namespace SSW.CleanArchitecture.Domain.Entities; - -public record TodoItemId(Guid Value); - -public class TodoItem : BaseEntity -{ - // NOTE: private setters for behavior we want to encapsulate, and public setters for properties that don't have behavior - - public string? Title { get; private set; } - public string? Note { get; set; } - public PriorityLevel Priority { get; set; } - public DateTime Reminder { get; set; } - public bool Done { get; private set; } - - private TodoItem() { } - - public static TodoItem Create(string title) - { - ArgumentException.ThrowIfNullOrEmpty(title, nameof(title)); - - var todoItem = new TodoItem - { - Title = title, - Priority = PriorityLevel.None, - Done = false - }; - - todoItem.AddDomainEvent(new TodoItemCreatedEvent(todoItem)); - - return todoItem; - } - - public static TodoItem Create(string title, string note, PriorityLevel priority, DateTime reminder) - { - var todoItem = Create(title); - todoItem.Note = note; - todoItem.Priority = priority; - todoItem.Reminder = reminder; - - return todoItem; - } - - public void Complete() - { - Done = true; - - AddDomainEvent(new TodoItemCompletedEvent(this)); - } +using SSW.CleanArchitecture.Domain.Common.Base; + +namespace SSW.CleanArchitecture.Domain.TodoItems; + +public record TodoItemId(Guid Value); + +public class TodoItem : BaseEntity +{ + // NOTE: private setters for behavior we want to encapsulate, and public setters for properties that don't have behavior + + public string? Title { get; private set; } + public string? Note { get; set; } + public PriorityLevel Priority { get; set; } + public DateTime Reminder { get; set; } + public bool Done { get; private set; } + + private TodoItem() { } + + public static TodoItem Create(string title) + { + ArgumentException.ThrowIfNullOrEmpty(title, nameof(title)); + + var todoItem = new TodoItem + { + Title = title, + Priority = PriorityLevel.None, + Done = false + }; + + todoItem.AddDomainEvent(new TodoItemCreatedEvent(todoItem)); + + return todoItem; + } + + public static TodoItem Create(string title, string note, PriorityLevel priority, DateTime reminder) + { + var todoItem = Create(title); + todoItem.Note = note; + todoItem.Priority = priority; + todoItem.Reminder = reminder; + + return todoItem; + } + + public void Complete() + { + Done = true; + + AddDomainEvent(new TodoItemCompletedEvent(this)); + } } \ No newline at end of file diff --git a/src/Domain/Events/TodoItemCompletedEvent.cs b/src/Domain/TodoItems/TodoItemCompletedEvent.cs similarity index 56% rename from src/Domain/Events/TodoItemCompletedEvent.cs rename to src/Domain/TodoItems/TodoItemCompletedEvent.cs index e124108c..e0b8a9a2 100644 --- a/src/Domain/Events/TodoItemCompletedEvent.cs +++ b/src/Domain/TodoItems/TodoItemCompletedEvent.cs @@ -1,6 +1,5 @@ using SSW.CleanArchitecture.Domain.Common.Base; -using SSW.CleanArchitecture.Domain.Entities; -namespace SSW.CleanArchitecture.Domain.Events; +namespace SSW.CleanArchitecture.Domain.TodoItems; public record TodoItemCompletedEvent(TodoItem Item) : DomainEvent; diff --git a/src/Domain/Events/TodoItemCreatedEvent.cs b/src/Domain/TodoItems/TodoItemCreatedEvent.cs similarity index 56% rename from src/Domain/Events/TodoItemCreatedEvent.cs rename to src/Domain/TodoItems/TodoItemCreatedEvent.cs index bab5625c..60af38c4 100644 --- a/src/Domain/Events/TodoItemCreatedEvent.cs +++ b/src/Domain/TodoItems/TodoItemCreatedEvent.cs @@ -1,6 +1,5 @@ using SSW.CleanArchitecture.Domain.Common.Base; -using SSW.CleanArchitecture.Domain.Entities; -namespace SSW.CleanArchitecture.Domain.Events; +namespace SSW.CleanArchitecture.Domain.TodoItems; public record TodoItemCreatedEvent(TodoItem Item) : DomainEvent; diff --git a/src/Infrastructure/Persistence/ApplicationDbContext.cs b/src/Infrastructure/Persistence/ApplicationDbContext.cs index df8cdef2..ff78d5be 100644 --- a/src/Infrastructure/Persistence/ApplicationDbContext.cs +++ b/src/Infrastructure/Persistence/ApplicationDbContext.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore; using SSW.CleanArchitecture.Application.Common.Interfaces; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; using SSW.CleanArchitecture.Infrastructure.Persistence.Interceptors; using System.Reflection; diff --git a/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs b/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs index 4f769eea..86492506 100644 --- a/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs +++ b/src/Infrastructure/Persistence/ApplicationDbContextInitializer.cs @@ -1,8 +1,7 @@ -using SSW.CleanArchitecture.Domain.Entities; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using SSW.CleanArchitecture.Domain.Enum; using FluentValidation.Validators; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Infrastructure.Persistence; diff --git a/src/Infrastructure/Persistence/Configuration/TodoItemConfiguration.cs b/src/Infrastructure/Persistence/Configuration/TodoItemConfiguration.cs index 44fe3f03..ec707231 100644 --- a/src/Infrastructure/Persistence/Configuration/TodoItemConfiguration.cs +++ b/src/Infrastructure/Persistence/Configuration/TodoItemConfiguration.cs @@ -1,6 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Infrastructure.Persistence.Configuration; diff --git a/tests/Application.IntegrationTests/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandTests.cs b/tests/Application.IntegrationTests/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandTests.cs index 4a977c28..00dad5c4 100644 --- a/tests/Application.IntegrationTests/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandTests.cs +++ b/tests/Application.IntegrationTests/Features/TodoItems/Commands/CreateTodoItem/CreateTodoItemCommandTests.cs @@ -1,7 +1,7 @@ using SSW.CleanArchitecture.Application.Common.Exceptions; using SSW.CleanArchitecture.Application.Features.TodoItems.Commands.CreateTodoItem; using SSW.CleanArchitecture.Application.IntegrationTests.TestHelpers; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.IntegrationTests.Features.TodoItems.Commands.CreateTodoItem; diff --git a/tests/Application.IntegrationTests/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsQueryTests.cs b/tests/Application.IntegrationTests/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsQueryTests.cs index 50200ebe..6efcfc57 100644 --- a/tests/Application.IntegrationTests/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsQueryTests.cs +++ b/tests/Application.IntegrationTests/Features/TodoItems/Queries/GetAllTodoItems/GetAllTodoItemsQueryTests.cs @@ -1,7 +1,7 @@ using Bogus; using SSW.CleanArchitecture.Application.Features.TodoItems.Queries.GetAllTodoItems; using SSW.CleanArchitecture.Application.IntegrationTests.TestHelpers; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.IntegrationTests.Features.TodoItems.Queries.GetAllTodoItems; diff --git a/tests/Application.UnitTests/Features/TodoItems/Specifications/AllTodoItemSpecTests.cs b/tests/Application.UnitTests/Features/TodoItems/Specifications/AllTodoItemSpecTests.cs index bc8552a2..a9425b08 100644 --- a/tests/Application.UnitTests/Features/TodoItems/Specifications/AllTodoItemSpecTests.cs +++ b/tests/Application.UnitTests/Features/TodoItems/Specifications/AllTodoItemSpecTests.cs @@ -1,6 +1,6 @@ using Bogus; using SSW.CleanArchitecture.Application.Features.TodoItems.Specifications; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.UnitTests.Features.TodoItems.Specifications; diff --git a/tests/Application.UnitTests/Features/TodoItems/Specifications/TodoItemByTitleSpecTests.cs b/tests/Application.UnitTests/Features/TodoItems/Specifications/TodoItemByTitleSpecTests.cs index ef045c4f..689ccdba 100644 --- a/tests/Application.UnitTests/Features/TodoItems/Specifications/TodoItemByTitleSpecTests.cs +++ b/tests/Application.UnitTests/Features/TodoItems/Specifications/TodoItemByTitleSpecTests.cs @@ -1,5 +1,5 @@ using SSW.CleanArchitecture.Application.Features.TodoItems.Specifications; -using SSW.CleanArchitecture.Domain.Entities; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Application.UnitTests.Features.TodoItems.Specifications; diff --git a/tests/Domain.UnitTests/Entities/TodoItemTests.cs b/tests/Domain.UnitTests/Entities/TodoItemTests.cs index 19913e25..b01eab58 100644 --- a/tests/Domain.UnitTests/Entities/TodoItemTests.cs +++ b/tests/Domain.UnitTests/Entities/TodoItemTests.cs @@ -1,5 +1,4 @@ -using SSW.CleanArchitecture.Domain.Entities; -using SSW.CleanArchitecture.Domain.Events; +using SSW.CleanArchitecture.Domain.TodoItems; namespace SSW.CleanArchitecture.Domain.UnitTests.Entities; @@ -17,7 +16,7 @@ public void Create_Should_Succeed_When_Title_Valid() // Assert todoItem.Should().NotBeNull(); todoItem.Title.Should().Be(title); - todoItem.Priority.Should().Be(Enum.PriorityLevel.None); + todoItem.Priority.Should().Be(PriorityLevel.None); } [Fact]