From 396181c036a336e7e8bcd5d000b40d7abe140b27 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 12 Apr 2022 06:50:03 -0400 Subject: [PATCH 01/17] Upgrade to .NET 6 --- src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj | 4 ++-- src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj | 4 ++-- src/YuckQi.Domain/YuckQi.Domain.csproj | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index f3734d7..72892b2 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -1,10 +1,10 @@  - netstandard2.0 + net6.0 true Kevin J Lambert - 1.3.0 + 6.0.0 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index f56e229..45f456e 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -1,10 +1,10 @@  - netstandard2.0 + net6.0 true Kevin J Lambert - 1.3.0 + 6.0.0 LICENSE A .NET library providing domain validation fundamentals. diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index 7d9c6a6..53568e0 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -1,10 +1,10 @@  - netstandard2.0 + net6.0 true Kevin J Lambert - 1.3.0 + 6.0.0 LICENSE A .NET library for bootstrapping a domain model project. From 7d0ef3e4defcfa6820dc4cb945015d772eef1e8a Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 12 Apr 2022 06:50:57 -0400 Subject: [PATCH 02/17] Update all packages --- .../YuckQi.Domain.Validation.csproj | 2 +- .../YuckQi.Domain.Validation.UnitTests.csproj | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 45f456e..6687d94 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -17,7 +17,7 @@ - + diff --git a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj index f55e89e..94a2db4 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj +++ b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj @@ -8,10 +8,13 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From c4b493e7239fbb3be42f175b82630e558f9b5869 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 12 Apr 2022 06:53:53 -0400 Subject: [PATCH 03/17] Formatted all files --- .../Abstract/ITypeEntityService.cs | 17 +- .../Models/TypeSearchCriteria.cs | 13 +- .../Exceptions/DomainValidationException.cs | 53 +++-- .../Extensions/AbstractValidatorExtensions.cs | 29 ++- src/YuckQi.Domain.Validation/Result.cs | 65 +++--- src/YuckQi.Domain.Validation/ResultCode.cs | 51 +++-- src/YuckQi.Domain.Validation/ResultDetail.cs | 51 +++-- src/YuckQi.Domain.Validation/ResultMessage.cs | 37 ++-- src/YuckQi.Domain.Validation/ResultType.cs | 13 +- .../Aspects/Abstract/IActivated.cs | 9 +- .../Aspects/Abstract/IAudited.cs | 11 +- .../Aspects/Abstract/ICreated.cs | 9 +- .../Aspects/Abstract/IDeleted.cs | 9 +- .../Aspects/Abstract/IRevised.cs | 9 +- src/YuckQi.Domain/Aspects/Abstract/IType.cs | 13 +- .../Entities/Abstract/EntityBase.cs | 9 +- .../Entities/Abstract/IEntity.cs | 9 +- .../Abstract/IMultiTenantEntity.cs | 11 +- .../Abstract/MultiTenantEntityBase.cs | 11 +- .../ValueObjects/Abstract/IPage.cs | 21 +- src/YuckQi.Domain/ValueObjects/Date.cs | 201 +++++++++--------- src/YuckQi.Domain/ValueObjects/Page.cs | 63 +++--- 22 files changed, 346 insertions(+), 368 deletions(-) diff --git a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs index 5e95658..6d443d4 100644 --- a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs +++ b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs @@ -6,14 +6,13 @@ using YuckQi.Domain.Validation; using YuckQi.Domain.ValueObjects.Abstract; -namespace YuckQi.Domain.Services.Abstract +namespace YuckQi.Domain.Services.Abstract; + +public interface ITypeEntityService where TTypeEntity : IEntity, IType where TKey : struct { - public interface ITypeEntityService where TTypeEntity : IEntity, IType where TKey : struct - { - Task> CreateAsync(TTypeEntity entity); - Task> GetAsync(Guid identifier); - Task> GetAsync(TKey key); - Task> ModifyAsync(TTypeEntity entity); - Task>> SearchAsync(TypeSearchCriteria criteria = null); - } + Task> CreateAsync(TTypeEntity entity); + Task> GetAsync(Guid identifier); + Task> GetAsync(TKey key); + Task> ModifyAsync(TTypeEntity entity); + Task>> SearchAsync(TypeSearchCriteria criteria = null); } diff --git a/src/YuckQi.Domain.Services/Models/TypeSearchCriteria.cs b/src/YuckQi.Domain.Services/Models/TypeSearchCriteria.cs index 96a772a..914cf3a 100644 --- a/src/YuckQi.Domain.Services/Models/TypeSearchCriteria.cs +++ b/src/YuckQi.Domain.Services/Models/TypeSearchCriteria.cs @@ -1,12 +1,11 @@ using System; using YuckQi.Domain.ValueObjects.Abstract; -namespace YuckQi.Domain.Services.Models +namespace YuckQi.Domain.Services.Models; + +public class TypeSearchCriteria : IPage { - public class TypeSearchCriteria : IPage - { - public String Name { get; set; } - public Int32 PageNumber { get; set; } - public Int32 PageSize { get; set; } - } + public String Name { get; set; } + public Int32 PageNumber { get; set; } + public Int32 PageSize { get; set; } } diff --git a/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs b/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs index baf4fd6..505f518 100644 --- a/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs +++ b/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs @@ -1,48 +1,47 @@ using System; using System.Linq; -namespace YuckQi.Domain.Validation.Exceptions -{ - public class DomainValidationException : ApplicationException - { - #region Constants +namespace YuckQi.Domain.Validation.Exceptions; - private const String DefaultErrorMessage = "Something went wrong."; +public class DomainValidationException : ApplicationException +{ + #region Constants - #endregion + private const String DefaultErrorMessage = "Something went wrong."; + #endregion - #region Properties - public Result Result { get; } + #region Properties - #endregion + public Result Result { get; } + #endregion - #region Constructors - public DomainValidationException(Result result) : base(GetErrorMessage(result)) - { - Result = result; - } + #region Constructors - #endregion + public DomainValidationException(Result result) : base(GetErrorMessage(result)) + { + Result = result; + } + #endregion - #region Supporting Methods - private static String GetErrorMessage(Result result) - { - if (result == null) - return DefaultErrorMessage; + #region Supporting Methods - var count = result.Detail.Count(t => t.Type == ResultType.Error); - var noun = count == 1 ? "error" : "errors"; - var message = $"Domain model has {count} {noun} after validation."; + private static String GetErrorMessage(Result result) + { + if (result == null) + return DefaultErrorMessage; - return message; - } + var count = result.Detail.Count(t => t.Type == ResultType.Error); + var noun = count == 1 ? "error" : "errors"; + var message = $"Domain model has {count} {noun} after validation."; - #endregion + return message; } + + #endregion } diff --git a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs index 8c4bafa..61d49df 100644 --- a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs +++ b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs @@ -4,25 +4,24 @@ using FluentValidation; using FluentValidation.Results; -namespace YuckQi.Domain.Validation.Extensions +namespace YuckQi.Domain.Validation.Extensions; + +public static class AbstractValidatorExtensions { - public static class AbstractValidatorExtensions + public static Result GetResult(this AbstractValidator validator, T item, String failedValidationMessageId) { - public static Result GetResult(this AbstractValidator validator, T item, String failedValidationMessageId) - { - var result = validator.Validate(item); - if (result == null) - throw new ArgumentNullException(nameof(result)); + var result = validator.Validate(item); + if (result == null) + throw new ArgumentNullException(nameof(result)); - if (result.IsValid) - return new Result(item); + if (result.IsValid) + return new Result(item); - return new Result(default, GetResultDetail(result, failedValidationMessageId)); - } + return new Result(default, GetResultDetail(result, failedValidationMessageId)); + } - private static IReadOnlyCollection GetResultDetail(ValidationResult result, String failedValidationMessageId) - { - return result?.Errors.Select(t => new ResultDetail(ResultCode.InvalidRequestDetail, new ResultMessage(failedValidationMessageId, t.ErrorMessage), t.PropertyName)).ToList(); - } + private static IReadOnlyCollection GetResultDetail(ValidationResult result, String failedValidationMessageId) + { + return result?.Errors.Select(t => new ResultDetail(ResultCode.InvalidRequestDetail, new ResultMessage(failedValidationMessageId, t.ErrorMessage), t.PropertyName)).ToList(); } } diff --git a/src/YuckQi.Domain.Validation/Result.cs b/src/YuckQi.Domain.Validation/Result.cs index 796ce3b..4192ea7 100644 --- a/src/YuckQi.Domain.Validation/Result.cs +++ b/src/YuckQi.Domain.Validation/Result.cs @@ -2,60 +2,59 @@ using System.Collections.Generic; using System.Linq; -namespace YuckQi.Domain.Validation -{ - public class Result - { - #region Properties +namespace YuckQi.Domain.Validation; - public IReadOnlyCollection Detail { get; } +public class Result +{ + #region Properties - public Boolean IsValid => Detail.All(t => t.Type != ResultType.Error); + public IReadOnlyCollection Detail { get; } - #endregion + public Boolean IsValid => Detail.All(t => t.Type != ResultType.Error); + #endregion - #region Constructors - public Result(IReadOnlyCollection detail) - { - Detail = detail ?? Array.Empty(); - } + #region Constructors - #endregion + public Result(IReadOnlyCollection detail) + { + Detail = detail ?? Array.Empty(); } - public class Result : Result - { - #region Properties + #endregion +} - public T Payload { get; } +public class Result : Result +{ + #region Properties - #endregion + public T Payload { get; } + #endregion - #region Constructors - public Result(ResultDetail detail) : this(new List { detail }) { } + #region Constructors - public Result(IReadOnlyCollection detail) : base(detail) { } + public Result(ResultDetail detail) : this(new List { detail }) { } - public Result(T payload, IReadOnlyCollection detail = null) : base(detail) - { - Payload = payload; - } + public Result(IReadOnlyCollection detail) : base(detail) { } - #endregion + public Result(T payload, IReadOnlyCollection detail = null) : base(detail) + { + Payload = payload; + } + #endregion - #region Public Methods - public static Result ConstraintViolation(TKey key, String message = null) where TKey : struct => new Result(ResultDetail.ConstraintViolation(key, message)); + #region Public Methods - public Boolean HasResultCode(ResultCode resultCode) => Detail.Any(t => t.Code == resultCode); + public static Result ConstraintViolation(TKey key, String message = null) where TKey : struct => new(ResultDetail.ConstraintViolation(key, message)); - public static Result NotFound(TKey key, String message = null) where TKey : struct => new Result(ResultDetail.NotFound(key, message)); + public Boolean HasResultCode(ResultCode resultCode) => Detail.Any(t => t.Code == resultCode); - #endregion - } + public static Result NotFound(TKey key, String message = null) where TKey : struct => new(ResultDetail.NotFound(key, message)); + + #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultCode.cs b/src/YuckQi.Domain.Validation/ResultCode.cs index 561a410..93fcd58 100644 --- a/src/YuckQi.Domain.Validation/ResultCode.cs +++ b/src/YuckQi.Domain.Validation/ResultCode.cs @@ -1,50 +1,49 @@ using System; -namespace YuckQi.Domain.Validation +namespace YuckQi.Domain.Validation; + +public readonly struct ResultCode { - public readonly struct ResultCode - { - #region Private Members + #region Private Members - private readonly String _code; + private readonly String _code; - #endregion + #endregion - #region Implicit Operators + #region Implicit Operators - public static implicit operator String(ResultCode resultCode) => resultCode._code; + public static implicit operator String(ResultCode resultCode) => resultCode._code; - #endregion + #endregion - #region Constants + #region Constants - public static readonly ResultCode ConstraintViolation = new ResultCode(nameof(ConstraintViolation)); - public static readonly ResultCode InvalidRequestDetail = new ResultCode(nameof(InvalidRequestDetail)); - public static readonly ResultCode NotFound = new ResultCode(nameof(NotFound)); + public static readonly ResultCode ConstraintViolation = new(nameof(ConstraintViolation)); + public static readonly ResultCode InvalidRequestDetail = new(nameof(InvalidRequestDetail)); + public static readonly ResultCode NotFound = new(nameof(NotFound)); - #endregion + #endregion - #region Constructors + #region Constructors - public ResultCode(String code) - { - _code = code; - } + public ResultCode(String code) + { + _code = code; + } - #endregion + #endregion - #region Public Methods + #region Public Methods - public override Boolean Equals(Object obj) => obj != null && String.Equals(this, (ResultCode) obj); + public override Boolean Equals(Object obj) => obj != null && String.Equals(this, (ResultCode) obj); - public override Int32 GetHashCode() => _code.GetHashCode(); + public override Int32 GetHashCode() => _code.GetHashCode(); - public override String ToString() => _code; + public override String ToString() => _code; - #endregion - } + #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultDetail.cs b/src/YuckQi.Domain.Validation/ResultDetail.cs index a192760..23b76ca 100644 --- a/src/YuckQi.Domain.Validation/ResultDetail.cs +++ b/src/YuckQi.Domain.Validation/ResultDetail.cs @@ -1,46 +1,45 @@ using System; -namespace YuckQi.Domain.Validation -{ - public class ResultDetail - { - #region Private Members +namespace YuckQi.Domain.Validation; - private readonly ResultCode _code; +public class ResultDetail +{ + #region Private Members - #endregion + private readonly ResultCode _code; + #endregion - #region Constants - public static ResultDetail ConstraintViolation(TKey key, String message = null) where TKey : struct => new ResultDetail(ResultCode.ConstraintViolation, ResultMessage.ConstraintConflict(key, message)); - public static ResultDetail NotFound(TKey key, String message = null) where TKey : struct => new ResultDetail(ResultCode.NotFound, ResultMessage.NotFound(key, message)); + #region Constants - #endregion + public static ResultDetail ConstraintViolation(TKey key, String message = null) where TKey : struct => new(ResultCode.ConstraintViolation, ResultMessage.ConstraintConflict(key, message)); + public static ResultDetail NotFound(TKey key, String message = null) where TKey : struct => new(ResultCode.NotFound, ResultMessage.NotFound(key, message)); + #endregion - #region Properties - public ResultMessage Message { get; } - public String Property { get; } - public ResultType Type { get; } + #region Properties - public String Code => _code; + public ResultMessage Message { get; } + public String Property { get; } + public ResultType Type { get; } - #endregion + public String Code => _code; + #endregion - #region Constructors - public ResultDetail(ResultCode code, ResultMessage message, String property = null, ResultType type = ResultType.Error) - { - _code = code; + #region Constructors - Message = message; - Property = property; - Type = type; - } + public ResultDetail(ResultCode code, ResultMessage message, String property = null, ResultType type = ResultType.Error) + { + _code = code; - #endregion + Message = message; + Property = property; + Type = type; } + + #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultMessage.cs b/src/YuckQi.Domain.Validation/ResultMessage.cs index 673be00..d5ba219 100644 --- a/src/YuckQi.Domain.Validation/ResultMessage.cs +++ b/src/YuckQi.Domain.Validation/ResultMessage.cs @@ -1,33 +1,32 @@ using System; -namespace YuckQi.Domain.Validation +namespace YuckQi.Domain.Validation; + +public readonly struct ResultMessage { - public readonly struct ResultMessage - { - #region Properties + #region Properties - public String Id { get; } - public String Text { get; } + public String Id { get; } + public String Text { get; } - #endregion + #endregion - #region Constructors + #region Constructors - public ResultMessage(String id, String text = null) - { - Id = id; - Text = text; - } + public ResultMessage(String id, String text = null) + { + Id = id; + Text = text; + } - #endregion + #endregion - #region Public Methods + #region Public Methods - public static ResultMessage ConstraintConflict(TKey key, String message = null) where TKey : struct => new ResultMessage($"{ResultCode.ConstraintViolation.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' already exists."); - public static ResultMessage NotFound(TKey key, String message = null) where TKey : struct => new ResultMessage($"{ResultCode.NotFound.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' could not be found."); + public static ResultMessage ConstraintConflict(TKey key, String message = null) where TKey : struct => new($"{ResultCode.ConstraintViolation.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' already exists."); + public static ResultMessage NotFound(TKey key, String message = null) where TKey : struct => new($"{ResultCode.NotFound.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' could not be found."); - #endregion - } + #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultType.cs b/src/YuckQi.Domain.Validation/ResultType.cs index f2519a0..3aa6980 100644 --- a/src/YuckQi.Domain.Validation/ResultType.cs +++ b/src/YuckQi.Domain.Validation/ResultType.cs @@ -1,9 +1,8 @@ -namespace YuckQi.Domain.Validation +namespace YuckQi.Domain.Validation; + +public enum ResultType { - public enum ResultType - { - Unknown = 0, - Warning = 1, - Error = 2 - } + Unknown = 0, + Warning = 1, + Error = 2 } diff --git a/src/YuckQi.Domain/Aspects/Abstract/IActivated.cs b/src/YuckQi.Domain/Aspects/Abstract/IActivated.cs index f622f0d..4615402 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IActivated.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IActivated.cs @@ -1,9 +1,8 @@ using System; -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface IActivated { - public interface IActivated - { - DateTime? ActivationMomentUtc { get; set; } - } + DateTime? ActivationMomentUtc { get; set; } } diff --git a/src/YuckQi.Domain/Aspects/Abstract/IAudited.cs b/src/YuckQi.Domain/Aspects/Abstract/IAudited.cs index 1466339..14ef1c5 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IAudited.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IAudited.cs @@ -1,8 +1,7 @@ -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface IAudited : ICreated, IRevised { - public interface IAudited : ICreated, IRevised - { - TIdentity CreatedBy { get; set; } - TIdentity RevisedBy { get; set; } - } + TIdentity CreatedBy { get; set; } + TIdentity RevisedBy { get; set; } } diff --git a/src/YuckQi.Domain/Aspects/Abstract/ICreated.cs b/src/YuckQi.Domain/Aspects/Abstract/ICreated.cs index 3f7f2d4..63bed96 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/ICreated.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/ICreated.cs @@ -1,9 +1,8 @@ using System; -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface ICreated { - public interface ICreated - { - DateTime CreationMomentUtc { get; set; } - } + DateTime CreationMomentUtc { get; set; } } diff --git a/src/YuckQi.Domain/Aspects/Abstract/IDeleted.cs b/src/YuckQi.Domain/Aspects/Abstract/IDeleted.cs index d29fe24..fcd3bb2 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IDeleted.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IDeleted.cs @@ -1,9 +1,8 @@ using System; -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface IDeleted { - public interface IDeleted - { - DateTime? DeletionMomentUtc { get; set; } - } + DateTime? DeletionMomentUtc { get; set; } } diff --git a/src/YuckQi.Domain/Aspects/Abstract/IRevised.cs b/src/YuckQi.Domain/Aspects/Abstract/IRevised.cs index 9713f4d..9600a09 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IRevised.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IRevised.cs @@ -1,9 +1,8 @@ using System; -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface IRevised { - public interface IRevised - { - DateTime RevisionMomentUtc { get; set; } - } + DateTime RevisionMomentUtc { get; set; } } diff --git a/src/YuckQi.Domain/Aspects/Abstract/IType.cs b/src/YuckQi.Domain/Aspects/Abstract/IType.cs index 5a07671..ae71b4c 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IType.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IType.cs @@ -1,11 +1,10 @@ using System; -namespace YuckQi.Domain.Aspects.Abstract +namespace YuckQi.Domain.Aspects.Abstract; + +public interface IType { - public interface IType - { - Guid Identifier { get; set; } - String Name { get; set; } - String ShortName { get; set; } - } + Guid Identifier { get; set; } + String Name { get; set; } + String ShortName { get; set; } } diff --git a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs index c6a7efa..7034825 100644 --- a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs +++ b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs @@ -1,7 +1,6 @@ -namespace YuckQi.Domain.Entities.Abstract +namespace YuckQi.Domain.Entities.Abstract; + +public abstract class EntityBase : IEntity where TKey : struct { - public abstract class EntityBase : IEntity where TKey : struct - { - public TKey Key { get; set; } - } + public TKey Key { get; set; } } diff --git a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs index fec07d6..23e8b99 100644 --- a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs +++ b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs @@ -1,7 +1,6 @@ -namespace YuckQi.Domain.Entities.Abstract +namespace YuckQi.Domain.Entities.Abstract; + +public interface IEntity where TKey : struct { - public interface IEntity where TKey : struct - { - TKey Key { get; set; } - } + TKey Key { get; set; } } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs index c9b2657..10ffe2c 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs @@ -1,12 +1,11 @@ using System; using YuckQi.Domain.Entities.Abstract; -namespace YuckQi.Domain.Entities.MultiTenant.Abstract +namespace YuckQi.Domain.Entities.MultiTenant.Abstract; + +public interface IMultiTenantEntity : IEntity where TKey : struct where TTenantKey : struct { - public interface IMultiTenantEntity : IEntity where TKey : struct where TTenantKey : struct - { - TTenantKey TenantId { get; set; } + TTenantKey TenantId { get; set; } - Boolean IsValidTenant(TTenantKey? tenantId); - } + Boolean IsValidTenant(TTenantKey? tenantId); } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs index 0530eab..8ba8f96 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs @@ -1,12 +1,11 @@ using System; using YuckQi.Domain.Entities.Abstract; -namespace YuckQi.Domain.Entities.MultiTenant.Abstract +namespace YuckQi.Domain.Entities.MultiTenant.Abstract; + +public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TKey : struct where TTenantKey : struct { - public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TKey : struct where TTenantKey : struct - { - public TTenantKey TenantId { get; set; } + public TTenantKey TenantId { get; set; } - public Boolean IsValidTenant(TTenantKey? tenantId) => TenantId.Equals(tenantId); - } + public Boolean IsValidTenant(TTenantKey? tenantId) => TenantId.Equals(tenantId); } diff --git a/src/YuckQi.Domain/ValueObjects/Abstract/IPage.cs b/src/YuckQi.Domain/ValueObjects/Abstract/IPage.cs index fc27dd8..23ac801 100644 --- a/src/YuckQi.Domain/ValueObjects/Abstract/IPage.cs +++ b/src/YuckQi.Domain/ValueObjects/Abstract/IPage.cs @@ -1,17 +1,16 @@ using System; using System.Collections.Generic; -namespace YuckQi.Domain.ValueObjects.Abstract +namespace YuckQi.Domain.ValueObjects.Abstract; + +public interface IPage { - public interface IPage - { - Int32 PageNumber { get; } - Int32 PageSize { get; } - } + Int32 PageNumber { get; } + Int32 PageSize { get; } +} - public interface IPage : IPage - { - IReadOnlyCollection Items { get; } - Int32 TotalCount { get; } - } +public interface IPage : IPage +{ + IReadOnlyCollection Items { get; } + Int32 TotalCount { get; } } diff --git a/src/YuckQi.Domain/ValueObjects/Date.cs b/src/YuckQi.Domain/ValueObjects/Date.cs index 4f7e60e..77381ca 100644 --- a/src/YuckQi.Domain/ValueObjects/Date.cs +++ b/src/YuckQi.Domain/ValueObjects/Date.cs @@ -26,174 +26,173 @@ THE SOFTWARE. using System.Globalization; using System.Runtime.Serialization; -namespace YuckQi.Domain.ValueObjects +namespace YuckQi.Domain.ValueObjects; + +[Serializable] +public readonly struct Date : IComparable, IFormattable, ISerializable, IComparable, IEquatable { - [Serializable] - public readonly struct Date : IComparable, IFormattable, ISerializable, IComparable, IEquatable - { - private readonly DateTime _value; + private readonly DateTime _value; - public static readonly Date MaxValue = new Date(DateTime.MaxValue); - public static readonly Date MinValue = new Date(DateTime.MinValue); + public static readonly Date MaxValue = new(DateTime.MaxValue); + public static readonly Date MinValue = new(DateTime.MinValue); - public Date(Int32 year, Int32 month, Int32 day) - { - _value = new DateTime(year, month, day); - } + public Date(Int32 year, Int32 month, Int32 day) + { + _value = new DateTime(year, month, day); + } - public Date(DateTime dateTime) - { - _value = dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerDay); - } + public Date(DateTime dateTime) + { + _value = dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerDay); + } - public Date(DateTimeOffset dateTimeOffset) : this(dateTimeOffset.DateTime) { } + public Date(DateTimeOffset dateTimeOffset) : this(dateTimeOffset.DateTime) { } - private Date(SerializationInfo info, StreamingContext context) - { - _value = DateTime.FromFileTime(info.GetInt64("ticks")); - } + private Date(SerializationInfo info, StreamingContext context) + { + _value = DateTime.FromFileTime(info.GetInt64("ticks")); + } - public static TimeSpan operator -(Date d1, Date d2) => d1._value - d2._value; + public static TimeSpan operator -(Date d1, Date d2) => d1._value - d2._value; - public static Date operator -(Date d, TimeSpan t) => new Date(d._value - t); + public static Date operator -(Date d, TimeSpan t) => new(d._value - t); - public static Boolean operator !=(Date d1, Date d2) => d1._value != d2._value; + public static Boolean operator !=(Date d1, Date d2) => d1._value != d2._value; - public static Date operator +(Date d, TimeSpan t) => new Date(d._value + t); + public static Date operator +(Date d, TimeSpan t) => new(d._value + t); - public static Boolean operator <(Date d1, Date d2) => d1._value < d2._value; + public static Boolean operator <(Date d1, Date d2) => d1._value < d2._value; - public static Boolean operator <=(Date d1, Date d2) => d1._value <= d2._value; + public static Boolean operator <=(Date d1, Date d2) => d1._value <= d2._value; - public static Boolean operator ==(Date d1, Date d2) => d1._value == d2._value; + public static Boolean operator ==(Date d1, Date d2) => d1._value == d2._value; - public static Boolean operator >(Date d1, Date d2) => d1._value > d2._value; + public static Boolean operator >(Date d1, Date d2) => d1._value > d2._value; - public static Boolean operator >=(Date d1, Date d2) => d1._value >= d2._value; + public static Boolean operator >=(Date d1, Date d2) => d1._value >= d2._value; - public static implicit operator DateTime(Date d) => d._value; + public static implicit operator DateTime(Date d) => d._value; - public static explicit operator Date(DateTime d) => new Date(d); + public static explicit operator Date(DateTime d) => new(d); - public static implicit operator DateTimeOffset(Date d) => d._value; + public static implicit operator DateTimeOffset(Date d) => d._value; - public static explicit operator Date(DateTimeOffset d) => new Date(d); + public static explicit operator Date(DateTimeOffset d) => new(d); - public Int32 Day => _value.Day; + public Int32 Day => _value.Day; - public DayOfWeek DayOfWeek => _value.DayOfWeek; + public DayOfWeek DayOfWeek => _value.DayOfWeek; - public Int32 DayOfYear => _value.DayOfYear; + public Int32 DayOfYear => _value.DayOfYear; - public Int32 Month => _value.Month; + public Int32 Month => _value.Month; - public static Date Today => new Date(DateTime.Today); + public static Date Today => new(DateTime.Today); - public Int32 Year => _value.Year; + public Int32 Year => _value.Year; - public Int64 Ticks => _value.Ticks; + public Int64 Ticks => _value.Ticks; - public Date AddDays(Int32 value) => new Date(_value.AddDays(value)); + public Date AddDays(Int32 value) => new(_value.AddDays(value)); - public Date AddMonths(Int32 value) => new Date(_value.AddMonths(value)); + public Date AddMonths(Int32 value) => new(_value.AddMonths(value)); - public Date AddYears(Int32 value) => new Date(_value.AddYears(value)); + public Date AddYears(Int32 value) => new(_value.AddYears(value)); - public static Int32 Compare(Date d1, Date d2) => d1.CompareTo(d2); + public static Int32 Compare(Date d1, Date d2) => d1.CompareTo(d2); - public Int32 CompareTo(Date value) => _value.CompareTo(value._value); + public Int32 CompareTo(Date value) => _value.CompareTo(value._value); - public Int32 CompareTo(Object value) => _value.CompareTo(value); + public Int32 CompareTo(Object value) => _value.CompareTo(value); - public static Int32 DaysInMonth(Int32 year, Int32 month) => DateTime.DaysInMonth(year, month); + public static Int32 DaysInMonth(Int32 year, Int32 month) => DateTime.DaysInMonth(year, month); - public Boolean Equals(Date value) => _value.Equals(value._value); + public Boolean Equals(Date value) => _value.Equals(value._value); - public override Boolean Equals(Object value) => value is Date date && _value.Equals(date._value); + public override Boolean Equals(Object value) => value is Date date && _value.Equals(date._value); - public override Int32 GetHashCode() => _value.GetHashCode(); + public override Int32 GetHashCode() => _value.GetHashCode(); - public static Boolean Equals(Date d1, Date d2) => d1._value.Equals(d2._value); + public static Boolean Equals(Date d1, Date d2) => d1._value.Equals(d2._value); - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("ticks", _value.Ticks); - } + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("ticks", _value.Ticks); + } - public static Boolean IsLeapYear(Int32 year) => DateTime.IsLeapYear(year); + public static Boolean IsLeapYear(Int32 year) => DateTime.IsLeapYear(year); - public static Date Parse(String s) => new Date(DateTime.Parse(s)); + public static Date Parse(String s) => new(DateTime.Parse(s)); - public static Date Parse(String s, IFormatProvider provider) => new Date(DateTime.Parse(s, provider)); + public static Date Parse(String s, IFormatProvider provider) => new(DateTime.Parse(s, provider)); - public static Date Parse(String s, IFormatProvider provider, DateTimeStyles style) => new Date(DateTime.Parse(s, provider, style)); + public static Date Parse(String s, IFormatProvider provider, DateTimeStyles style) => new(DateTime.Parse(s, provider, style)); - public static Date ParseExact(String s, String format, IFormatProvider provider) => new Date(DateTime.ParseExact(s, format, provider)); + public static Date ParseExact(String s, String format, IFormatProvider provider) => new(DateTime.ParseExact(s, format, provider)); - public static Date ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) => new Date(DateTime.ParseExact(s, format, provider, style)); + public static Date ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) => new(DateTime.ParseExact(s, format, provider, style)); - public static Date ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) => new Date(DateTime.ParseExact(s, formats, provider, style)); + public static Date ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) => new(DateTime.ParseExact(s, formats, provider, style)); - public TimeSpan Subtract(Date value) => this - value; + public TimeSpan Subtract(Date value) => this - value; - public Date Subtract(TimeSpan value) => this - value; + public Date Subtract(TimeSpan value) => this - value; - public static Date ToDate(DateTime dateTime) => new Date(dateTime); + public static Date ToDate(DateTime dateTime) => new(dateTime); - public static Date ToDate(DateTimeOffset dateTimeOffset) => new Date(dateTimeOffset); + public static Date ToDate(DateTimeOffset dateTimeOffset) => new(dateTimeOffset); - public String ToLongString() => _value.ToLongDateString(); + public String ToLongString() => _value.ToLongDateString(); - public String ToShortString() => _value.ToShortDateString(); + public String ToShortString() => _value.ToShortDateString(); - public override String ToString() => ToShortString(); + public override String ToString() => ToShortString(); - public String ToString(IFormatProvider provider) => _value.ToString(provider); + public String ToString(IFormatProvider provider) => _value.ToString(provider); - public String ToString(String format) - { - if (format == "O" || format == "o" || format == "s") - return ToString("yyyy-MM-dd"); + public String ToString(String format) + { + if (format == "O" || format == "o" || format == "s") + return ToString("yyyy-MM-dd"); - return _value.ToString(format); - } + return _value.ToString(format); + } - public String ToString(String format, IFormatProvider provider) => _value.ToString(format, provider); + public String ToString(String format, IFormatProvider provider) => _value.ToString(format, provider); - public static Boolean TryParse(String s, out Date result) - { - var success = DateTime.TryParse(s, out var d); + public static Boolean TryParse(String s, out Date result) + { + var success = DateTime.TryParse(s, out var d); - result = new Date(d); + result = new Date(d); - return success; - } + return success; + } - public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParse(s, provider, style, out var d); + public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles style, out Date result) + { + var success = DateTime.TryParse(s, provider, style, out var d); - result = new Date(d); + result = new Date(d); - return success; - } + return success; + } - public static Boolean TryParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParseExact(s, format, provider, style, out var d); + public static Boolean TryParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style, out Date result) + { + var success = DateTime.TryParseExact(s, format, provider, style, out var d); - result = new Date(d); + result = new Date(d); - return success; - } + return success; + } - public static Boolean TryParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParseExact(s, formats, provider, style, out var d); + public static Boolean TryParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style, out Date result) + { + var success = DateTime.TryParseExact(s, formats, provider, style, out var d); - result = new Date(d); + result = new Date(d); - return success; - } + return success; } } diff --git a/src/YuckQi.Domain/ValueObjects/Page.cs b/src/YuckQi.Domain/ValueObjects/Page.cs index 549abd4..aff18fb 100644 --- a/src/YuckQi.Domain/ValueObjects/Page.cs +++ b/src/YuckQi.Domain/ValueObjects/Page.cs @@ -2,51 +2,50 @@ using System.Collections.Generic; using YuckQi.Domain.ValueObjects.Abstract; -namespace YuckQi.Domain.ValueObjects -{ - public readonly struct Page : IPage - { - #region Properties +namespace YuckQi.Domain.ValueObjects; - public Int32 PageNumber { get; } - public Int32 PageSize { get; } +public readonly struct Page : IPage +{ + #region Properties - #endregion + public Int32 PageNumber { get; } + public Int32 PageSize { get; } + #endregion - #region Constructors - public Page(Int32 page, Int32 size) - { - PageNumber = page; - PageSize = size; - } + #region Constructors - #endregion + public Page(Int32 page, Int32 size) + { + PageNumber = page; + PageSize = size; } - public readonly struct Page : IPage - { - #region Properties + #endregion +} - public IReadOnlyCollection Items { get; } - public Int32 PageNumber { get; } - public Int32 PageSize { get; } - public Int32 TotalCount { get; } +public readonly struct Page : IPage +{ + #region Properties - #endregion + public IReadOnlyCollection Items { get; } + public Int32 PageNumber { get; } + public Int32 PageSize { get; } + public Int32 TotalCount { get; } + #endregion - #region Constructors - public Page(IReadOnlyCollection items, Int32 total, Int32 page, Int32 size) - { - Items = items ?? new List(); - PageNumber = page; - PageSize = size; - TotalCount = total; - } + #region Constructors - #endregion + public Page(IReadOnlyCollection items, Int32 total, Int32 page, Int32 size) + { + Items = items ?? new List(); + PageNumber = page; + PageSize = size; + TotalCount = total; } + + #endregion } From 1998bd8c0a75e52a813835641a443ae0b03c8a53 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Sat, 28 May 2022 06:55:43 -0400 Subject: [PATCH 04/17] Renamed 'key' to 'identifier' --- src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs | 4 ++-- src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj | 2 +- src/YuckQi.Domain.Validation/Result.cs | 4 ++-- src/YuckQi.Domain.Validation/ResultDetail.cs | 4 ++-- src/YuckQi.Domain.Validation/ResultMessage.cs | 4 ++-- .../YuckQi.Domain.Validation.csproj | 2 +- src/YuckQi.Domain/Entities/Abstract/EntityBase.cs | 4 ++-- src/YuckQi.Domain/Entities/Abstract/IEntity.cs | 4 ++-- .../Entities/MultiTenant/Abstract/IMultiTenantEntity.cs | 6 +++--- .../Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs | 6 +++--- src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs index 6d443d4..fd4ecb5 100644 --- a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs +++ b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs @@ -8,11 +8,11 @@ namespace YuckQi.Domain.Services.Abstract; -public interface ITypeEntityService where TTypeEntity : IEntity, IType where TKey : struct +public interface ITypeEntityService where TTypeEntity : IEntity, IType where TIdentifier : struct { Task> CreateAsync(TTypeEntity entity); Task> GetAsync(Guid identifier); - Task> GetAsync(TKey key); + Task> GetAsync(TIdentifier identifier); Task> ModifyAsync(TTypeEntity entity); Task>> SearchAsync(TypeSearchCriteria criteria = null); } diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index 72892b2..c4b3777 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.0 + 6.0.1 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/Result.cs b/src/YuckQi.Domain.Validation/Result.cs index 4192ea7..59c6029 100644 --- a/src/YuckQi.Domain.Validation/Result.cs +++ b/src/YuckQi.Domain.Validation/Result.cs @@ -50,11 +50,11 @@ public Result(T payload, IReadOnlyCollection detail = null) : base #region Public Methods - public static Result ConstraintViolation(TKey key, String message = null) where TKey : struct => new(ResultDetail.ConstraintViolation(key, message)); + public static Result ConstraintViolation(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultDetail.ConstraintViolation(identifier, message)); public Boolean HasResultCode(ResultCode resultCode) => Detail.Any(t => t.Code == resultCode); - public static Result NotFound(TKey key, String message = null) where TKey : struct => new(ResultDetail.NotFound(key, message)); + public static Result NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultDetail.NotFound(identifier, message)); #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultDetail.cs b/src/YuckQi.Domain.Validation/ResultDetail.cs index 23b76ca..1080ef2 100644 --- a/src/YuckQi.Domain.Validation/ResultDetail.cs +++ b/src/YuckQi.Domain.Validation/ResultDetail.cs @@ -13,8 +13,8 @@ public class ResultDetail #region Constants - public static ResultDetail ConstraintViolation(TKey key, String message = null) where TKey : struct => new(ResultCode.ConstraintViolation, ResultMessage.ConstraintConflict(key, message)); - public static ResultDetail NotFound(TKey key, String message = null) where TKey : struct => new(ResultCode.NotFound, ResultMessage.NotFound(key, message)); + public static ResultDetail ConstraintViolation(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultCode.ConstraintViolation, ResultMessage.ConstraintConflict(identifier, message)); + public static ResultDetail NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultCode.NotFound, ResultMessage.NotFound(identifier, message)); #endregion diff --git a/src/YuckQi.Domain.Validation/ResultMessage.cs b/src/YuckQi.Domain.Validation/ResultMessage.cs index d5ba219..e720278 100644 --- a/src/YuckQi.Domain.Validation/ResultMessage.cs +++ b/src/YuckQi.Domain.Validation/ResultMessage.cs @@ -25,8 +25,8 @@ public ResultMessage(String id, String text = null) #region Public Methods - public static ResultMessage ConstraintConflict(TKey key, String message = null) where TKey : struct => new($"{ResultCode.ConstraintViolation.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' already exists."); - public static ResultMessage NotFound(TKey key, String message = null) where TKey : struct => new($"{ResultCode.NotFound.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{key}' could not be found."); + public static ResultMessage ConstraintConflict(TIdentifier identifier, String message = null) where TIdentifier : struct => new($"{ResultCode.ConstraintViolation.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{identifier}' already exists."); + public static ResultMessage NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new($"{ResultCode.NotFound.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{identifier}' could not be found."); #endregion } diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 6687d94..30ee162 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.0 + 6.0.1 LICENSE A .NET library providing domain validation fundamentals. diff --git a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs index 7034825..5c9616b 100644 --- a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs +++ b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs @@ -1,6 +1,6 @@ namespace YuckQi.Domain.Entities.Abstract; -public abstract class EntityBase : IEntity where TKey : struct +public abstract class EntityBase : IEntity where TIdentifier : struct { - public TKey Key { get; set; } + public TIdentifier Identifier { get; set; } } diff --git a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs index 23e8b99..32f745d 100644 --- a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs +++ b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs @@ -1,6 +1,6 @@ namespace YuckQi.Domain.Entities.Abstract; -public interface IEntity where TKey : struct +public interface IEntity where TIdentifier : struct { - TKey Key { get; set; } + TIdentifier Identifier { get; set; } } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs index 10ffe2c..6346129 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs @@ -3,9 +3,9 @@ namespace YuckQi.Domain.Entities.MultiTenant.Abstract; -public interface IMultiTenantEntity : IEntity where TKey : struct where TTenantKey : struct +public interface IMultiTenantEntity : IEntity where TIdentifier : struct where TTenantIdentifier : struct { - TTenantKey TenantId { get; set; } + TTenantIdentifier TenantIdentifier { get; set; } - Boolean IsValidTenant(TTenantKey? tenantId); + Boolean IsValidTenant(TTenantIdentifier? tenantIdentifier); } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs index 8ba8f96..94a9f4c 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs @@ -3,9 +3,9 @@ namespace YuckQi.Domain.Entities.MultiTenant.Abstract; -public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TKey : struct where TTenantKey : struct +public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TIdentifier : struct where TTenantIdentifier : struct { - public TTenantKey TenantId { get; set; } + public TTenantIdentifier TenantIdentifier { get; set; } - public Boolean IsValidTenant(TTenantKey? tenantId) => TenantId.Equals(tenantId); + public Boolean IsValidTenant(TTenantIdentifier? tenantIdentifier) => TenantIdentifier.Equals(tenantIdentifier); } diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index 53568e0..c881b69 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.0 + 6.0.1 LICENSE A .NET library for bootstrapping a domain model project. From f567173052ba22db62c67138f7c365f4fa0bcbfb Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Sun, 29 May 2022 13:48:27 -0400 Subject: [PATCH 05/17] Removed 'identifier' from IType --- src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj | 2 +- src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj | 2 +- src/YuckQi.Domain/Aspects/Abstract/IType.cs | 1 - src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index c4b3777..26fb117 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.1 + 6.0.2 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 30ee162..427c597 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.1 + 6.0.2 LICENSE A .NET library providing domain validation fundamentals. diff --git a/src/YuckQi.Domain/Aspects/Abstract/IType.cs b/src/YuckQi.Domain/Aspects/Abstract/IType.cs index ae71b4c..0e0259f 100644 --- a/src/YuckQi.Domain/Aspects/Abstract/IType.cs +++ b/src/YuckQi.Domain/Aspects/Abstract/IType.cs @@ -4,7 +4,6 @@ namespace YuckQi.Domain.Aspects.Abstract; public interface IType { - Guid Identifier { get; set; } String Name { get; set; } String ShortName { get; set; } } diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index c881b69..7f05d73 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.1 + 6.0.2 LICENSE A .NET library for bootstrapping a domain model project. From eb1bceed1711a78dcdc910f0ea8003e6ba119ad9 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Mon, 30 May 2022 10:41:28 -0400 Subject: [PATCH 06/17] Remove GetAsync(Guid) from ITypeEntityService --- src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs | 4 +--- src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj | 2 +- src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj | 2 +- src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs index fd4ecb5..8894a9d 100644 --- a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs +++ b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs @@ -1,5 +1,4 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using YuckQi.Domain.Aspects.Abstract; using YuckQi.Domain.Entities.Abstract; using YuckQi.Domain.Services.Models; @@ -11,7 +10,6 @@ namespace YuckQi.Domain.Services.Abstract; public interface ITypeEntityService where TTypeEntity : IEntity, IType where TIdentifier : struct { Task> CreateAsync(TTypeEntity entity); - Task> GetAsync(Guid identifier); Task> GetAsync(TIdentifier identifier); Task> ModifyAsync(TTypeEntity entity); Task>> SearchAsync(TypeSearchCriteria criteria = null); diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index 26fb117..5e18ef6 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.2 + 6.0.3 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 427c597..c631fa8 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.2 + 6.0.3 LICENSE A .NET library providing domain validation fundamentals. diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index 7f05d73..df9739e 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.2 + 6.0.3 LICENSE A .NET library for bootstrapping a domain model project. From 911b815ae050090bf7791281783c5f37b2a7f0d0 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 7 Jun 2022 08:20:57 -0400 Subject: [PATCH 07/17] Added support for ValidateAsync --- .../YuckQi.Domain.Services.csproj | 2 +- .../Extensions/AbstractValidatorExtensions.cs | 26 +++++++++++++++---- .../YuckQi.Domain.Validation.csproj | 2 +- src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index 5e18ef6..42527e5 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.3 + 6.0.4 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs index 61d49df..38eb93b 100644 --- a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs +++ b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using FluentValidation; using FluentValidation.Results; @@ -10,14 +11,29 @@ public static class AbstractValidatorExtensions { public static Result GetResult(this AbstractValidator validator, T item, String failedValidationMessageId) { - var result = validator.Validate(item); - if (result == null) - throw new ArgumentNullException(nameof(result)); + var validationResult = validator.Validate(item); + var result = BuildResult(validationResult, item, failedValidationMessageId); - if (result.IsValid) + return result; + } + + public static async Task> GetResultAsync(this AbstractValidator validator, T item, String failedValidationMessageId) + { + var validationResult = await validator.ValidateAsync(item); + var result = BuildResult(validationResult, item, failedValidationMessageId); + + return result; + } + + private static Result BuildResult(ValidationResult validationResult, T item, String failedValidationMessageId) + { + if (validationResult == null) + throw new ArgumentNullException(nameof(validationResult)); + + if (validationResult.IsValid) return new Result(item); - return new Result(default, GetResultDetail(result, failedValidationMessageId)); + return new Result(default, GetResultDetail(validationResult, failedValidationMessageId)); } private static IReadOnlyCollection GetResultDetail(ValidationResult result, String failedValidationMessageId) diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index c631fa8..5dc9f4a 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.3 + 6.0.4 LICENSE A .NET library providing domain validation fundamentals. diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index df9739e..ce0d333 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.3 + 6.0.4 LICENSE A .NET library for bootstrapping a domain model project. From 664cddefe0533bc102209984595d3c5861025cbe Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 16 Aug 2022 18:33:50 -0400 Subject: [PATCH 08/17] Removed Async suffix and added support for CancellationToken --- .../Abstract/ITypeEntityService.cs | 11 +++-- .../YuckQi.Domain.Services.csproj | 2 +- .../Exceptions/DomainValidationException.cs | 47 ------------------- .../Extensions/AbstractValidatorExtensions.cs | 5 +- .../YuckQi.Domain.Validation.csproj | 4 +- src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- .../YuckQi.Domain.Validation.UnitTests.csproj | 2 +- 7 files changed, 14 insertions(+), 59 deletions(-) delete mode 100644 src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs diff --git a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs index 8894a9d..869666b 100644 --- a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs +++ b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using YuckQi.Domain.Aspects.Abstract; using YuckQi.Domain.Entities.Abstract; using YuckQi.Domain.Services.Models; @@ -9,8 +10,8 @@ namespace YuckQi.Domain.Services.Abstract; public interface ITypeEntityService where TTypeEntity : IEntity, IType where TIdentifier : struct { - Task> CreateAsync(TTypeEntity entity); - Task> GetAsync(TIdentifier identifier); - Task> ModifyAsync(TTypeEntity entity); - Task>> SearchAsync(TypeSearchCriteria criteria = null); + Task> Create(TTypeEntity entity, CancellationToken cancellationToken = default); + Task> Get(TIdentifier identifier, CancellationToken cancellationToken = default); + Task> Modify(TTypeEntity entity, CancellationToken cancellationToken = default); + Task>> Search(TypeSearchCriteria criteria = null, CancellationToken cancellationToken = default); } diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index 42527e5..1059d96 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.4 + 6.1.0 LICENSE A .NET library for bootstrapping a domain services project. diff --git a/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs b/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs deleted file mode 100644 index 505f518..0000000 --- a/src/YuckQi.Domain.Validation/Exceptions/DomainValidationException.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Linq; - -namespace YuckQi.Domain.Validation.Exceptions; - -public class DomainValidationException : ApplicationException -{ - #region Constants - - private const String DefaultErrorMessage = "Something went wrong."; - - #endregion - - - #region Properties - - public Result Result { get; } - - #endregion - - - #region Constructors - - public DomainValidationException(Result result) : base(GetErrorMessage(result)) - { - Result = result; - } - - #endregion - - - #region Supporting Methods - - private static String GetErrorMessage(Result result) - { - if (result == null) - return DefaultErrorMessage; - - var count = result.Detail.Count(t => t.Type == ResultType.Error); - var noun = count == 1 ? "error" : "errors"; - var message = $"Domain model has {count} {noun} after validation."; - - return message; - } - - #endregion -} diff --git a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs index 38eb93b..1ad3182 100644 --- a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs +++ b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using FluentValidation; using FluentValidation.Results; @@ -17,9 +18,9 @@ public static Result GetResult(this AbstractValidator validator, T item return result; } - public static async Task> GetResultAsync(this AbstractValidator validator, T item, String failedValidationMessageId) + public static async Task> GetResult(this AbstractValidator validator, T item, String failedValidationMessageId, CancellationToken cancellationToken) { - var validationResult = await validator.ValidateAsync(item); + var validationResult = await validator.ValidateAsync(item, cancellationToken); var result = BuildResult(validationResult, item, failedValidationMessageId); return result; diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 5dc9f4a..a5846c1 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.4 + 6.1.0 LICENSE A .NET library providing domain validation fundamentals. @@ -17,7 +17,7 @@ - + diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index ce0d333..1cc504f 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.0.4 + 6.1.0 LICENSE A .NET library for bootstrapping a domain model project. diff --git a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj index 94a2db4..991345d 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj +++ b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj @@ -8,7 +8,7 @@ - + From ee30324c0fb6502a077e1cd12eeba562ae0a9d21 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 6 Dec 2022 15:31:59 -0500 Subject: [PATCH 09/17] Updated packages --- .../YuckQi.Domain.Validation.csproj | 2 +- .../YuckQi.Domain.Validation.UnitTests.csproj | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index a5846c1..0895f75 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -17,7 +17,7 @@ - + diff --git a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj index 991345d..1d9a5bf 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj +++ b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj @@ -8,10 +8,10 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive From bf0c959c2dbf0b58d8794c4e2351f3e0370da377 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Thu, 16 Mar 2023 17:15:36 -0400 Subject: [PATCH 10/17] Updated packages --- YuckQi.Domain.sln | 9 ++++++++- src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj | 1 + .../YuckQi.Domain.Validation.csproj | 3 ++- src/YuckQi.Domain/YuckQi.Domain.csproj | 1 + .../YuckQi.Domain.Validation.UnitTests.csproj | 4 ++-- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/YuckQi.Domain.sln b/YuckQi.Domain.sln index 5c44514..cec7856 100644 --- a/YuckQi.Domain.sln +++ b/YuckQi.Domain.sln @@ -9,12 +9,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YuckQi.Domain.Validation", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YuckQi.Domain.Services", "src\YuckQi.Domain.Services\YuckQi.Domain.Services.csproj", "{0F24D228-C35A-4DB0-BD64-3E33A3D02B02}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YuckQi.Domain.Validation.UnitTests", "test\YuckQi.Domain.Validation.UnitTests\YuckQi.Domain.Validation.UnitTests.csproj", "{153AC057-A111-4A2D-950B-8FB331A1124E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YuckQi.Domain.Validation.UnitTests", "test\YuckQi.Domain.Validation.UnitTests\YuckQi.Domain.Validation.UnitTests.csproj", "{153AC057-A111-4A2D-950B-8FB331A1124E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{5B0AF740-A98C-402C-BE34-FD3E95384BA3}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Unit Tests", "Unit Tests", "{4012738B-4956-416F-AC49-28E5F00297B3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YuckQi.Domain.UnitTests", "test\YuckQi.Domain.UnitTests\YuckQi.Domain.UnitTests.csproj", "{EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -37,6 +39,10 @@ Global {153AC057-A111-4A2D-950B-8FB331A1124E}.Debug|Any CPU.Build.0 = Debug|Any CPU {153AC057-A111-4A2D-950B-8FB331A1124E}.Release|Any CPU.ActiveCfg = Release|Any CPU {153AC057-A111-4A2D-950B-8FB331A1124E}.Release|Any CPU.Build.0 = Release|Any CPU + {EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -44,6 +50,7 @@ Global GlobalSection(NestedProjects) = preSolution {153AC057-A111-4A2D-950B-8FB331A1124E} = {4012738B-4956-416F-AC49-28E5F00297B3} {4012738B-4956-416F-AC49-28E5F00297B3} = {5B0AF740-A98C-402C-BE34-FD3E95384BA3} + {EA0EA1BA-AC4C-4D6C-839F-BF0F60A40346} = {4012738B-4956-416F-AC49-28E5F00297B3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7B79E244-ED98-4357-89F3-0E9586941E8B} diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index 1059d96..ee2b9a7 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -7,6 +7,7 @@ 6.1.0 LICENSE A .NET library for bootstrapping a domain services project. + enable diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 0895f75..0748a35 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -7,6 +7,7 @@ 6.1.0 LICENSE A .NET library providing domain validation fundamentals. + enable @@ -17,7 +18,7 @@ - + diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index 1cc504f..18bd0bf 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -7,6 +7,7 @@ 6.1.0 LICENSE A .NET library for bootstrapping a domain model project. + enable diff --git a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj index 1d9a5bf..1c9be1e 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj +++ b/test/YuckQi.Domain.Validation.UnitTests/YuckQi.Domain.Validation.UnitTests.csproj @@ -8,9 +8,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 39f512186a2c7492f984ed3cc96eb92ff1152a63 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Thu, 16 Mar 2023 17:16:04 -0400 Subject: [PATCH 11/17] Removed Date value object --- src/YuckQi.Domain/ValueObjects/Date.cs | 198 ------------------------- 1 file changed, 198 deletions(-) delete mode 100644 src/YuckQi.Domain/ValueObjects/Date.cs diff --git a/src/YuckQi.Domain/ValueObjects/Date.cs b/src/YuckQi.Domain/ValueObjects/Date.cs deleted file mode 100644 index 77381ca..0000000 --- a/src/YuckQi.Domain/ValueObjects/Date.cs +++ /dev/null @@ -1,198 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2015 Clay Anderson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -using System; -using System.Globalization; -using System.Runtime.Serialization; - -namespace YuckQi.Domain.ValueObjects; - -[Serializable] -public readonly struct Date : IComparable, IFormattable, ISerializable, IComparable, IEquatable -{ - private readonly DateTime _value; - - public static readonly Date MaxValue = new(DateTime.MaxValue); - public static readonly Date MinValue = new(DateTime.MinValue); - - public Date(Int32 year, Int32 month, Int32 day) - { - _value = new DateTime(year, month, day); - } - - public Date(DateTime dateTime) - { - _value = dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerDay); - } - - public Date(DateTimeOffset dateTimeOffset) : this(dateTimeOffset.DateTime) { } - - private Date(SerializationInfo info, StreamingContext context) - { - _value = DateTime.FromFileTime(info.GetInt64("ticks")); - } - - public static TimeSpan operator -(Date d1, Date d2) => d1._value - d2._value; - - public static Date operator -(Date d, TimeSpan t) => new(d._value - t); - - public static Boolean operator !=(Date d1, Date d2) => d1._value != d2._value; - - public static Date operator +(Date d, TimeSpan t) => new(d._value + t); - - public static Boolean operator <(Date d1, Date d2) => d1._value < d2._value; - - public static Boolean operator <=(Date d1, Date d2) => d1._value <= d2._value; - - public static Boolean operator ==(Date d1, Date d2) => d1._value == d2._value; - - public static Boolean operator >(Date d1, Date d2) => d1._value > d2._value; - - public static Boolean operator >=(Date d1, Date d2) => d1._value >= d2._value; - - public static implicit operator DateTime(Date d) => d._value; - - public static explicit operator Date(DateTime d) => new(d); - - public static implicit operator DateTimeOffset(Date d) => d._value; - - public static explicit operator Date(DateTimeOffset d) => new(d); - - public Int32 Day => _value.Day; - - public DayOfWeek DayOfWeek => _value.DayOfWeek; - - public Int32 DayOfYear => _value.DayOfYear; - - public Int32 Month => _value.Month; - - public static Date Today => new(DateTime.Today); - - public Int32 Year => _value.Year; - - public Int64 Ticks => _value.Ticks; - - public Date AddDays(Int32 value) => new(_value.AddDays(value)); - - public Date AddMonths(Int32 value) => new(_value.AddMonths(value)); - - public Date AddYears(Int32 value) => new(_value.AddYears(value)); - - public static Int32 Compare(Date d1, Date d2) => d1.CompareTo(d2); - - public Int32 CompareTo(Date value) => _value.CompareTo(value._value); - - public Int32 CompareTo(Object value) => _value.CompareTo(value); - - public static Int32 DaysInMonth(Int32 year, Int32 month) => DateTime.DaysInMonth(year, month); - - public Boolean Equals(Date value) => _value.Equals(value._value); - - public override Boolean Equals(Object value) => value is Date date && _value.Equals(date._value); - - public override Int32 GetHashCode() => _value.GetHashCode(); - - public static Boolean Equals(Date d1, Date d2) => d1._value.Equals(d2._value); - - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("ticks", _value.Ticks); - } - - public static Boolean IsLeapYear(Int32 year) => DateTime.IsLeapYear(year); - - public static Date Parse(String s) => new(DateTime.Parse(s)); - - public static Date Parse(String s, IFormatProvider provider) => new(DateTime.Parse(s, provider)); - - public static Date Parse(String s, IFormatProvider provider, DateTimeStyles style) => new(DateTime.Parse(s, provider, style)); - - public static Date ParseExact(String s, String format, IFormatProvider provider) => new(DateTime.ParseExact(s, format, provider)); - - public static Date ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) => new(DateTime.ParseExact(s, format, provider, style)); - - public static Date ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) => new(DateTime.ParseExact(s, formats, provider, style)); - - public TimeSpan Subtract(Date value) => this - value; - - public Date Subtract(TimeSpan value) => this - value; - - public static Date ToDate(DateTime dateTime) => new(dateTime); - - public static Date ToDate(DateTimeOffset dateTimeOffset) => new(dateTimeOffset); - - public String ToLongString() => _value.ToLongDateString(); - - public String ToShortString() => _value.ToShortDateString(); - - public override String ToString() => ToShortString(); - - public String ToString(IFormatProvider provider) => _value.ToString(provider); - - public String ToString(String format) - { - if (format == "O" || format == "o" || format == "s") - return ToString("yyyy-MM-dd"); - - return _value.ToString(format); - } - - public String ToString(String format, IFormatProvider provider) => _value.ToString(format, provider); - - public static Boolean TryParse(String s, out Date result) - { - var success = DateTime.TryParse(s, out var d); - - result = new Date(d); - - return success; - } - - public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParse(s, provider, style, out var d); - - result = new Date(d); - - return success; - } - - public static Boolean TryParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParseExact(s, format, provider, style, out var d); - - result = new Date(d); - - return success; - } - - public static Boolean TryParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style, out Date result) - { - var success = DateTime.TryParseExact(s, formats, provider, style, out var d); - - result = new Date(d); - - return success; - } -} From 707796becac2f77bb3aa560bbaec556d085cdf37 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Thu, 16 Mar 2023 17:19:36 -0400 Subject: [PATCH 12/17] Relaxed struct constraint in favor of IEquatable --- src/YuckQi.Domain/Entities/Abstract/EntityBase.cs | 8 +++++--- src/YuckQi.Domain/Entities/Abstract/IEntity.cs | 8 +++++--- .../Entities/MultiTenant/Abstract/IMultiTenantEntity.cs | 4 ++-- .../MultiTenant/Abstract/MultiTenantEntityBase.cs | 6 +++--- src/YuckQi.Domain/ValueObjects/Page.cs | 2 +- src/YuckQi.Domain/YuckQi.Domain.csproj | 2 +- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs index 5c9616b..6a4a044 100644 --- a/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs +++ b/src/YuckQi.Domain/Entities/Abstract/EntityBase.cs @@ -1,6 +1,8 @@ -namespace YuckQi.Domain.Entities.Abstract; +using System; -public abstract class EntityBase : IEntity where TIdentifier : struct +namespace YuckQi.Domain.Entities.Abstract; + +public abstract class EntityBase : IEntity where TIdentifier : IEquatable { - public TIdentifier Identifier { get; set; } + public TIdentifier? Identifier { get; set; } } diff --git a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs index 32f745d..27d4aaa 100644 --- a/src/YuckQi.Domain/Entities/Abstract/IEntity.cs +++ b/src/YuckQi.Domain/Entities/Abstract/IEntity.cs @@ -1,6 +1,8 @@ -namespace YuckQi.Domain.Entities.Abstract; +using System; -public interface IEntity where TIdentifier : struct +namespace YuckQi.Domain.Entities.Abstract; + +public interface IEntity where TIdentifier : IEquatable { - TIdentifier Identifier { get; set; } + TIdentifier? Identifier { get; set; } } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs index 6346129..f057c52 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/IMultiTenantEntity.cs @@ -3,9 +3,9 @@ namespace YuckQi.Domain.Entities.MultiTenant.Abstract; -public interface IMultiTenantEntity : IEntity where TIdentifier : struct where TTenantIdentifier : struct +public interface IMultiTenantEntity : IEntity where TIdentifier : IEquatable where TTenantIdentifier : IEquatable { - TTenantIdentifier TenantIdentifier { get; set; } + TTenantIdentifier? TenantIdentifier { get; set; } Boolean IsValidTenant(TTenantIdentifier? tenantIdentifier); } diff --git a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs index 94a9f4c..fc93617 100644 --- a/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs +++ b/src/YuckQi.Domain/Entities/MultiTenant/Abstract/MultiTenantEntityBase.cs @@ -3,9 +3,9 @@ namespace YuckQi.Domain.Entities.MultiTenant.Abstract; -public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TIdentifier : struct where TTenantIdentifier : struct +public abstract class MultiTenantEntityBase : EntityBase, IMultiTenantEntity where TIdentifier : IEquatable where TTenantIdentifier : IEquatable { - public TTenantIdentifier TenantIdentifier { get; set; } + public TTenantIdentifier? TenantIdentifier { get; set; } - public Boolean IsValidTenant(TTenantIdentifier? tenantIdentifier) => TenantIdentifier.Equals(tenantIdentifier); + public Boolean IsValidTenant(TTenantIdentifier? tenantIdentifier) => Equals(TenantIdentifier, tenantIdentifier); } diff --git a/src/YuckQi.Domain/ValueObjects/Page.cs b/src/YuckQi.Domain/ValueObjects/Page.cs index aff18fb..5e4b738 100644 --- a/src/YuckQi.Domain/ValueObjects/Page.cs +++ b/src/YuckQi.Domain/ValueObjects/Page.cs @@ -41,7 +41,7 @@ public Page(Int32 page, Int32 size) public Page(IReadOnlyCollection items, Int32 total, Int32 page, Int32 size) { - Items = items ?? new List(); + Items = items; PageNumber = page; PageSize = size; TotalCount = total; diff --git a/src/YuckQi.Domain/YuckQi.Domain.csproj b/src/YuckQi.Domain/YuckQi.Domain.csproj index 18bd0bf..3b45742 100644 --- a/src/YuckQi.Domain/YuckQi.Domain.csproj +++ b/src/YuckQi.Domain/YuckQi.Domain.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.1.0 + 6.2.0 LICENSE A .NET library for bootstrapping a domain model project. enable From 979dac0c61a0e32f8861af279cc60ff6b9aedf8c Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Thu, 16 Mar 2023 17:20:27 -0400 Subject: [PATCH 13/17] Added unit tests for YuckQi.Domain --- .../Entities/Abstract/EntityBaseTests.cs | 22 ++++++++++ .../Abstract/MultiTenantEntityBaseTests.cs | 40 +++++++++++++++++++ .../ValueObjects/PageTests.cs | 35 ++++++++++++++++ .../YuckQi.Domain.UnitTests.csproj | 24 +++++++++++ 4 files changed, 121 insertions(+) create mode 100644 test/YuckQi.Domain.UnitTests/Entities/Abstract/EntityBaseTests.cs create mode 100644 test/YuckQi.Domain.UnitTests/Entities/MultiTenant/Abstract/MultiTenantEntityBaseTests.cs create mode 100644 test/YuckQi.Domain.UnitTests/ValueObjects/PageTests.cs create mode 100644 test/YuckQi.Domain.UnitTests/YuckQi.Domain.UnitTests.csproj diff --git a/test/YuckQi.Domain.UnitTests/Entities/Abstract/EntityBaseTests.cs b/test/YuckQi.Domain.UnitTests/Entities/Abstract/EntityBaseTests.cs new file mode 100644 index 0000000..f28ba45 --- /dev/null +++ b/test/YuckQi.Domain.UnitTests/Entities/Abstract/EntityBaseTests.cs @@ -0,0 +1,22 @@ +using System; +using NUnit.Framework; +using YuckQi.Domain.Entities.Abstract; + +namespace YuckQi.Domain.UnitTests.Entities.Abstract; + +public class EntityBaseTests +{ + private class Entity : EntityBase { } + + [SetUp] + public void Setup() { } + + [Test] + public void EntityBase_GetIdentifier_HasExpectedValue() + { + var identifier = Guid.NewGuid(); + var entity = new Entity { Identifier = identifier }; + + Assert.That(entity.Identifier, Is.EqualTo(identifier)); + } +} diff --git a/test/YuckQi.Domain.UnitTests/Entities/MultiTenant/Abstract/MultiTenantEntityBaseTests.cs b/test/YuckQi.Domain.UnitTests/Entities/MultiTenant/Abstract/MultiTenantEntityBaseTests.cs new file mode 100644 index 0000000..1d6c8ae --- /dev/null +++ b/test/YuckQi.Domain.UnitTests/Entities/MultiTenant/Abstract/MultiTenantEntityBaseTests.cs @@ -0,0 +1,40 @@ +using System; +using NUnit.Framework; +using YuckQi.Domain.Entities.MultiTenant.Abstract; + +namespace YuckQi.Domain.UnitTests.Entities.MultiTenant.Abstract; + +public class MultiTenantEntityBaseTests +{ + private class MultiTenantEntity : MultiTenantEntityBase { } + + [SetUp] + public void Setup() { } + + [Test] + public void MultiTenantEntityBase_GetTenantIdentifier_HasExpectedValue() + { + var identifier = Guid.NewGuid().ToString("D").ToUpperInvariant(); + var entity = new MultiTenantEntity { Identifier = Guid.NewGuid(), TenantIdentifier = identifier }; + + Assert.That(entity.TenantIdentifier, Is.EqualTo(identifier)); + } + + [Test] + public void MultiTenantEntityBase_WithDifferentTenantIdentifier_IsNotValid() + { + var identifier = Guid.NewGuid().ToString("D").ToUpperInvariant(); + var entity = new MultiTenantEntity(); + + Assert.That(entity.IsValidTenant(identifier), Is.False); + } + + [Test] + public void MultiTenantEntityBase_WithSameTenantIdentifier_IsValid() + { + var identifier = Guid.NewGuid().ToString("D").ToUpperInvariant(); + var entity = new MultiTenantEntity { Identifier = Guid.NewGuid(), TenantIdentifier = identifier }; + + Assert.That(entity.IsValidTenant(identifier), Is.True); + } +} diff --git a/test/YuckQi.Domain.UnitTests/ValueObjects/PageTests.cs b/test/YuckQi.Domain.UnitTests/ValueObjects/PageTests.cs new file mode 100644 index 0000000..e8da6e5 --- /dev/null +++ b/test/YuckQi.Domain.UnitTests/ValueObjects/PageTests.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using YuckQi.Domain.ValueObjects; + +namespace YuckQi.Domain.UnitTests.ValueObjects; + +public class PageTests +{ + [SetUp] + public void Setup() { } + + [Test] + public void Page_Properties_HaveExpectedValues() + { + var page = new Page(1, 10); + + Assert.That(page.PageNumber, Is.EqualTo(1)); + Assert.That(page.PageSize, Is.EqualTo(10)); + } + + [Test] + public void PageOfString_Properties_HaveExpectedValues() + { + var items = new HashSet { "abc", "def", "ghi" }; + var page = new Page(items, items.Count, 1, 10); + + Assert.That(page.Items, Contains.Item("abc")); + Assert.That(page.Items, Contains.Item("def")); + Assert.That(page.Items, Contains.Item("ghi")); + Assert.That(page.PageNumber, Is.EqualTo(1)); + Assert.That(page.PageSize, Is.EqualTo(10)); + Assert.That(page.TotalCount, Is.EqualTo(3)); + } +} diff --git a/test/YuckQi.Domain.UnitTests/YuckQi.Domain.UnitTests.csproj b/test/YuckQi.Domain.UnitTests/YuckQi.Domain.UnitTests.csproj new file mode 100644 index 0000000..f4f3444 --- /dev/null +++ b/test/YuckQi.Domain.UnitTests/YuckQi.Domain.UnitTests.csproj @@ -0,0 +1,24 @@ + + + + net6.0 + enable + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + From 7fa559fc1b7fa3caa716787b257702bd861f125f Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Tue, 21 Mar 2023 10:41:04 -0400 Subject: [PATCH 14/17] Added ResultDetail tests --- .../Abstract/ITypeEntityService.cs | 7 ++-- .../YuckQi.Domain.Services.csproj | 2 +- .../Extensions/AbstractValidatorExtensions.cs | 16 ++++----- src/YuckQi.Domain.Validation/Result.cs | 33 +++-------------- src/YuckQi.Domain.Validation/ResultCode.cs | 36 ++++++------------- src/YuckQi.Domain.Validation/ResultDetail.cs | 35 ++++-------------- src/YuckQi.Domain.Validation/ResultMessage.cs | 25 +++++-------- .../YuckQi.Domain.Validation.csproj | 2 +- .../ResultCodeTests.cs | 35 ++++++++++++++++-- .../ResultDetailTests.cs | 35 ++++++++++++++++++ .../ResultTests.cs | 16 ++++----- 11 files changed, 118 insertions(+), 124 deletions(-) create mode 100644 test/YuckQi.Domain.Validation.UnitTests/ResultDetailTests.cs diff --git a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs index 869666b..f247889 100644 --- a/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs +++ b/src/YuckQi.Domain.Services/Abstract/ITypeEntityService.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System; +using System.Threading; using System.Threading.Tasks; using YuckQi.Domain.Aspects.Abstract; using YuckQi.Domain.Entities.Abstract; @@ -8,10 +9,10 @@ namespace YuckQi.Domain.Services.Abstract; -public interface ITypeEntityService where TTypeEntity : IEntity, IType where TIdentifier : struct +public interface ITypeEntityService where TTypeEntity : IEntity, IType where TIdentifier : IEquatable { Task> Create(TTypeEntity entity, CancellationToken cancellationToken = default); Task> Get(TIdentifier identifier, CancellationToken cancellationToken = default); Task> Modify(TTypeEntity entity, CancellationToken cancellationToken = default); - Task>> Search(TypeSearchCriteria criteria = null, CancellationToken cancellationToken = default); + Task>> Search(TypeSearchCriteria? criteria = null, CancellationToken cancellationToken = default); } diff --git a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj index ee2b9a7..d4a1557 100644 --- a/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj +++ b/src/YuckQi.Domain.Services/YuckQi.Domain.Services.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.1.0 + 6.2.0 LICENSE A .NET library for bootstrapping a domain services project. enable diff --git a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs index 1ad3182..a042eca 100644 --- a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs +++ b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs @@ -10,23 +10,23 @@ namespace YuckQi.Domain.Validation.Extensions; public static class AbstractValidatorExtensions { - public static Result GetResult(this AbstractValidator validator, T item, String failedValidationMessageId) + public static Result GetResult(this AbstractValidator validator, T item) { var validationResult = validator.Validate(item); - var result = BuildResult(validationResult, item, failedValidationMessageId); + var result = BuildResult(validationResult, item); return result; } - public static async Task> GetResult(this AbstractValidator validator, T item, String failedValidationMessageId, CancellationToken cancellationToken) + public static async Task> GetResult(this AbstractValidator validator, T item, CancellationToken cancellationToken) { var validationResult = await validator.ValidateAsync(item, cancellationToken); - var result = BuildResult(validationResult, item, failedValidationMessageId); + var result = BuildResult(validationResult, item); return result; } - private static Result BuildResult(ValidationResult validationResult, T item, String failedValidationMessageId) + private static Result BuildResult(ValidationResult validationResult, T item) { if (validationResult == null) throw new ArgumentNullException(nameof(validationResult)); @@ -34,11 +34,11 @@ private static Result BuildResult(ValidationResult validationResult, T ite if (validationResult.IsValid) return new Result(item); - return new Result(default, GetResultDetail(validationResult, failedValidationMessageId)); + return new Result(default, GetResultDetail(validationResult)); } - private static IReadOnlyCollection GetResultDetail(ValidationResult result, String failedValidationMessageId) + private static IReadOnlyCollection GetResultDetail(ValidationResult result) { - return result?.Errors.Select(t => new ResultDetail(ResultCode.InvalidRequestDetail, new ResultMessage(failedValidationMessageId, t.ErrorMessage), t.PropertyName)).ToList(); + return result.Errors.Select(t => new ResultDetail(new ResultMessage(t.ErrorMessage), ResultCode.InvalidRequestDetail, t.PropertyName)).ToList(); } } diff --git a/src/YuckQi.Domain.Validation/Result.cs b/src/YuckQi.Domain.Validation/Result.cs index 59c6029..b5dd54c 100644 --- a/src/YuckQi.Domain.Validation/Result.cs +++ b/src/YuckQi.Domain.Validation/Result.cs @@ -6,55 +6,32 @@ namespace YuckQi.Domain.Validation; public class Result { - #region Properties - public IReadOnlyCollection Detail { get; } public Boolean IsValid => Detail.All(t => t.Type != ResultType.Error); - #endregion - - - #region Constructors - - public Result(IReadOnlyCollection detail) + public Result(IReadOnlyCollection? detail) { Detail = detail ?? Array.Empty(); } - - #endregion } public class Result : Result { - #region Properties - - public T Payload { get; } - - #endregion - - - #region Constructors + public T? Payload { get; } public Result(ResultDetail detail) : this(new List { detail }) { } public Result(IReadOnlyCollection detail) : base(detail) { } - public Result(T payload, IReadOnlyCollection detail = null) : base(detail) + public Result(T? payload, IReadOnlyCollection? detail = null) : base(detail) { Payload = payload; } - #endregion - - - #region Public Methods - - public static Result ConstraintViolation(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultDetail.ConstraintViolation(identifier, message)); + public static Result ConstraintViolation(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(ResultDetail.ConstraintViolation(identifier, message)); public Boolean HasResultCode(ResultCode resultCode) => Detail.Any(t => t.Code == resultCode); - public static Result NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultDetail.NotFound(identifier, message)); - - #endregion + public static Result NotFound(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(ResultDetail.NotFound(identifier, message)); } diff --git a/src/YuckQi.Domain.Validation/ResultCode.cs b/src/YuckQi.Domain.Validation/ResultCode.cs index 93fcd58..f8126d1 100644 --- a/src/YuckQi.Domain.Validation/ResultCode.cs +++ b/src/YuckQi.Domain.Validation/ResultCode.cs @@ -4,46 +4,32 @@ namespace YuckQi.Domain.Validation; public readonly struct ResultCode { - #region Private Members - private readonly String _code; - #endregion - - - #region Implicit Operators - - public static implicit operator String(ResultCode resultCode) => resultCode._code; - - #endregion - - - #region Constants + public static implicit operator String(ResultCode code) => code._code; public static readonly ResultCode ConstraintViolation = new(nameof(ConstraintViolation)); public static readonly ResultCode InvalidRequestDetail = new(nameof(InvalidRequestDetail)); public static readonly ResultCode NotFound = new(nameof(NotFound)); - #endregion - - - #region Constructors + public ResultCode() : this(Guid.NewGuid().ToString()) { } public ResultCode(String code) { _code = code; } - #endregion - - - #region Public Methods - - public override Boolean Equals(Object obj) => obj != null && String.Equals(this, (ResultCode) obj); + public override Boolean Equals(Object? obj) + { + return obj switch + { + ResultCode other => String.Equals(this, other), + String other => String.Equals(this, other), + _ => false + }; + } public override Int32 GetHashCode() => _code.GetHashCode(); public override String ToString() => _code; - - #endregion } diff --git a/src/YuckQi.Domain.Validation/ResultDetail.cs b/src/YuckQi.Domain.Validation/ResultDetail.cs index 1080ef2..36d2ab3 100644 --- a/src/YuckQi.Domain.Validation/ResultDetail.cs +++ b/src/YuckQi.Domain.Validation/ResultDetail.cs @@ -4,42 +4,21 @@ namespace YuckQi.Domain.Validation; public class ResultDetail { - #region Private Members - - private readonly ResultCode _code; - - #endregion - - - #region Constants - - public static ResultDetail ConstraintViolation(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultCode.ConstraintViolation, ResultMessage.ConstraintConflict(identifier, message)); - public static ResultDetail NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new(ResultCode.NotFound, ResultMessage.NotFound(identifier, message)); - - #endregion - - - #region Properties + public static ResultDetail ConstraintViolation(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(ResultMessage.ConstraintConflict(identifier, message), ResultCode.ConstraintViolation); + public static ResultDetail NotFound(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(ResultMessage.NotFound(identifier, message), ResultCode.NotFound); + public ResultCode? Code { get; } public ResultMessage Message { get; } - public String Property { get; } + public String? Property { get; } public ResultType Type { get; } - public String Code => _code; - - #endregion - - - #region Constructors - - public ResultDetail(ResultCode code, ResultMessage message, String property = null, ResultType type = ResultType.Error) + public ResultDetail(ResultMessage message, ResultCode? code = null, String? property = null, ResultType type = ResultType.Error) { - _code = code; - + Code = code; Message = message; Property = property; Type = type; } - #endregion + public ResultDetail(String message, ResultCode? code = null, String? property = null, ResultType type = ResultType.Error) : this(new ResultMessage(message), code, property, type) { } } diff --git a/src/YuckQi.Domain.Validation/ResultMessage.cs b/src/YuckQi.Domain.Validation/ResultMessage.cs index e720278..95819cd 100644 --- a/src/YuckQi.Domain.Validation/ResultMessage.cs +++ b/src/YuckQi.Domain.Validation/ResultMessage.cs @@ -4,29 +4,20 @@ namespace YuckQi.Domain.Validation; public readonly struct ResultMessage { - #region Properties + private readonly String _message; - public String Id { get; } - public String Text { get; } + public static implicit operator String(ResultMessage message) => message._message; - #endregion + public ResultMessage() : this(String.Empty) { } - - #region Constructors - - public ResultMessage(String id, String text = null) + public ResultMessage(String message) { - Id = id; - Text = text; + _message = message; } - #endregion - - - #region Public Methods + public static ResultMessage ConstraintConflict(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(message ?? $"'{typeof(T).Name}' '{identifier}' already exists."); - public static ResultMessage ConstraintConflict(TIdentifier identifier, String message = null) where TIdentifier : struct => new($"{ResultCode.ConstraintViolation.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{identifier}' already exists."); - public static ResultMessage NotFound(TIdentifier identifier, String message = null) where TIdentifier : struct => new($"{ResultCode.NotFound.GetHashCode()}", message ?? $"'{typeof(T).Name}' '{identifier}' could not be found."); + public static ResultMessage NotFound(TIdentifier identifier, String? message = null) where TIdentifier : IEquatable => new(message ?? $"'{typeof(T).Name}' '{identifier}' could not be found."); - #endregion + public override String ToString() => _message; } diff --git a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj index 0748a35..c8183d2 100644 --- a/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj +++ b/src/YuckQi.Domain.Validation/YuckQi.Domain.Validation.csproj @@ -4,7 +4,7 @@ net6.0 true Kevin J Lambert - 6.1.0 + 6.2.0 LICENSE A .NET library providing domain validation fundamentals. enable diff --git a/test/YuckQi.Domain.Validation.UnitTests/ResultCodeTests.cs b/test/YuckQi.Domain.Validation.UnitTests/ResultCodeTests.cs index 43fe625..073344b 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/ResultCodeTests.cs +++ b/test/YuckQi.Domain.Validation.UnitTests/ResultCodeTests.cs @@ -10,11 +10,40 @@ public void Setup() { } [Test] public void ResultCode_WithSameCode_HasSameHashCode() { - var resultCodeA = new ResultCode("test"); + var resultCodeA = new ResultCode(); var hashCodeA = resultCodeA.GetHashCode(); - var resultCodeB = new ResultCode("test"); + var resultCodeB = new ResultCode(resultCodeA); var hashCodeB = resultCodeB.GetHashCode(); - Assert.AreEqual(hashCodeA, hashCodeB); + Assert.That(hashCodeA, Is.EqualTo(hashCodeB)); + } + + [Test] + public void ResultCode_StringConversion_IsAsExpected() + { + var resultCode = new ResultCode("test"); + + Assert.That(resultCode.ToString(), Is.EquivalentTo("test")); + } + + [Test] + public void ResultCode_Equality_IsAsExpected() + { + var resultCodeA = new ResultCode("test"); + var resultCodeB = new ResultCode("test"); + + // ReSharper disable SuspiciousTypeConversion.Global + Assert.That(resultCodeA.Equals("test"), Is.True); + Assert.That(resultCodeA.Equals(resultCodeB), Is.True); + Assert.That(resultCodeA.Equals(1234), Is.False); + // ReSharper restore SuspiciousTypeConversion.Global + } + + [Test] + public void ResultCode_ToString_IsAsExpected() + { + var resultCode = new ResultCode("test"); + + Assert.That(resultCode.ToString(), Is.EqualTo("test")); } } diff --git a/test/YuckQi.Domain.Validation.UnitTests/ResultDetailTests.cs b/test/YuckQi.Domain.Validation.UnitTests/ResultDetailTests.cs new file mode 100644 index 0000000..5458ab3 --- /dev/null +++ b/test/YuckQi.Domain.Validation.UnitTests/ResultDetailTests.cs @@ -0,0 +1,35 @@ +using System; +using NUnit.Framework; + +namespace YuckQi.Domain.Validation.UnitTests; + +public class ResultDetailTests +{ + [SetUp] + public void Setup() { } + + [Test] + public void ResultDetail_NotFound_HasNotFoundResultCode() + { + var detail = ResultDetail.NotFound(Guid.NewGuid()); + + Assert.That(detail.Code, Is.EqualTo(ResultCode.NotFound)); + } + + [Test] + public void ResultDetail_WithProperty_HasMatchingPropertyName() + { + var detail = new ResultDetail("thing missing", property: "property"); + + Assert.That(detail.Property, Is.EqualTo("property")); + } + + [Test] + public void ResultDetail_Message_HasMatchingValue() + { + var message = "this is a problem"; + var detail = new ResultDetail(message); + + Assert.That((String) detail.Message, Is.EqualTo(message)); + } +} diff --git a/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs b/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs index 527196c..c737e8c 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs +++ b/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs @@ -14,37 +14,33 @@ public void Result_NotFound_HasNotFoundResultCode() { var detail = new List { ResultDetail.NotFound(1), ResultDetail.ConstraintViolation(1) }.AsReadOnly(); var result = new Result(detail); - var hasNotFoundResultCode = result.HasResultCode(ResultCode.NotFound); - Assert.IsTrue(hasNotFoundResultCode); + Assert.That(result.HasResultCode(ResultCode.NotFound), Is.True); } [Test] public void Result_WithErrors_IsNotValid() { - var detail = new List { new(new ResultCode("test"), new ResultMessage("id")) }; + var detail = new List { new("test") }; var result = new Result("test", detail); - var isValid = result.IsValid; - Assert.IsFalse(isValid); + Assert.That(result.IsValid, Is.False); } [Test] public void Result_WithNoDetail_IsValid() { var result = new Result("test"); - var isValid = result.IsValid; - Assert.IsTrue(isValid); + Assert.That(result.IsValid, Is.True); } [Test] public void Result_WithOnlyWarnings_IsValid() { - var detail = new List { new(new ResultCode("test"), new ResultMessage("id"), type: ResultType.Warning) }; + var detail = new List { new(new ResultMessage("test"), type: ResultType.Warning) }; var result = new Result("test", detail); - var isValid = result.IsValid; - Assert.IsTrue(isValid); + Assert.That(result.IsValid, Is.True); } } From 4a30b4b713777c029d6364a336d9e4446d37d8a5 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Wed, 22 Mar 2023 06:57:02 -0400 Subject: [PATCH 15/17] Additional test coverage for Result --- .../ResultTests.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs b/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs index c737e8c..3c3bfce 100644 --- a/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs +++ b/test/YuckQi.Domain.Validation.UnitTests/ResultTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; namespace YuckQi.Domain.Validation.UnitTests; @@ -43,4 +44,34 @@ public void Result_WithOnlyWarnings_IsValid() Assert.That(result.IsValid, Is.True); } + + [Test] + public void Result_Payload_IsValid() + { + var payload = Guid.NewGuid().ToString(); + var result = new Result(payload); + + Assert.That(result.IsValid, Is.True); + Assert.That(result.Payload, Is.SameAs(payload)); + } + + [Test] + public void Result_ConstraintViolation_IsValid() + { + var identifier = Guid.NewGuid().ToString(); + var result = Result.ConstraintViolation(identifier); + var errors = result.Detail.Where(t => t.Code == ResultCode.ConstraintViolation); + + Assert.That(errors.Count(), Is.EqualTo(1)); + } + + [Test] + public void Result_NotFound_IsValid() + { + var identifier = Guid.NewGuid().ToString(); + var result = Result.NotFound(identifier); + var errors = result.Detail.Where(t => t.Code == ResultCode.NotFound); + + Assert.That(errors.Count(), Is.EqualTo(1)); + } } From 0192ba4f7bcecea85b2b6fa17c0892df3abb1ed1 Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Wed, 22 Mar 2023 07:04:14 -0400 Subject: [PATCH 16/17] Added ResultMessage tests --- .../ResultMessageTests.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 test/YuckQi.Domain.Validation.UnitTests/ResultMessageTests.cs diff --git a/test/YuckQi.Domain.Validation.UnitTests/ResultMessageTests.cs b/test/YuckQi.Domain.Validation.UnitTests/ResultMessageTests.cs new file mode 100644 index 0000000..0590fa9 --- /dev/null +++ b/test/YuckQi.Domain.Validation.UnitTests/ResultMessageTests.cs @@ -0,0 +1,25 @@ +using NUnit.Framework; + +namespace YuckQi.Domain.Validation.UnitTests; + +public class ResultMessageTests +{ + [SetUp] + public void Setup() { } + + [Test] + public void ResultMessage_ToString_MatchesOriginalMessage() + { + var message = new ResultMessage("this is a test"); + + Assert.That(message.ToString(), Is.EqualTo("this is a test")); + } + + [Test] + public void ResultMessage_WithNoMessage_IsNotNull() + { + var message = new ResultMessage(); + + Assert.That(message.ToString(), Is.Not.Null); + } +} From 57c0cf40d5061856232e9bc5223740f7eb3535af Mon Sep 17 00:00:00 2001 From: Kevin J Lambert Date: Wed, 22 Mar 2023 07:17:31 -0400 Subject: [PATCH 17/17] Added AbstractValidatorExtensions tests --- .../Extensions/AbstractValidatorExtensions.cs | 6 ++ .../AbstractValidatorExtensionsTests.cs | 62 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 test/YuckQi.Domain.Validation.UnitTests/Extensions/AbstractValidatorExtensionsTests.cs diff --git a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs index a042eca..cffb44b 100644 --- a/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs +++ b/src/YuckQi.Domain.Validation/Extensions/AbstractValidatorExtensions.cs @@ -12,6 +12,9 @@ public static class AbstractValidatorExtensions { public static Result GetResult(this AbstractValidator validator, T item) { + if (validator == null) + throw new ArgumentNullException(nameof(validator)); + var validationResult = validator.Validate(item); var result = BuildResult(validationResult, item); @@ -20,6 +23,9 @@ public static Result GetResult(this AbstractValidator validator, T item public static async Task> GetResult(this AbstractValidator validator, T item, CancellationToken cancellationToken) { + if (validator == null) + throw new ArgumentNullException(nameof(validator)); + var validationResult = await validator.ValidateAsync(item, cancellationToken); var result = BuildResult(validationResult, item); diff --git a/test/YuckQi.Domain.Validation.UnitTests/Extensions/AbstractValidatorExtensionsTests.cs b/test/YuckQi.Domain.Validation.UnitTests/Extensions/AbstractValidatorExtensionsTests.cs new file mode 100644 index 0000000..1777421 --- /dev/null +++ b/test/YuckQi.Domain.Validation.UnitTests/Extensions/AbstractValidatorExtensionsTests.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using FluentValidation; +using NUnit.Framework; +using YuckQi.Domain.Validation.Extensions; + +namespace YuckQi.Domain.Validation.UnitTests.Extensions; + +public class AbstractValidatorExtensionsTests +{ + public class StringValidator : AbstractValidator + { + public StringValidator() + { + RuleFor(t => t.Length).GreaterThan(1).WithMessage("it is too short"); + } + } + + [SetUp] + public void Setup() { } + + [Test] + public void AbstractValidator_GetResultWithValidItem_IsValid() + { + var validator = new StringValidator(); + var result = validator.GetResult("hello"); + + Assert.That(result.IsValid, Is.True); + } + + [Test] + public async Task AbstractValidator_GetResultAsyncWithValidItem_IsValid() + { + var validator = new StringValidator(); + var result = await validator.GetResult("hello", CancellationToken.None); + + Assert.That(result.IsValid, Is.True); + } + + [Test] + public void AbstractValidator_GetResultWithInvalidItem_HasDetail() + { + var validator = new StringValidator(); + var result = validator.GetResult(String.Empty); + + Assert.That(result.IsValid, Is.False); + Assert.That(result.Detail, Is.Not.Empty); + } + + [Test] + public void AbstractValidator_GetResultWithNullReference_ThrowsException() + { + Assert.That(() => AbstractValidatorExtensions.GetResult(null!, String.Empty), Throws.ArgumentNullException); + } + + [Test] + public void AbstractValidator_GetResultAsyncWithNullReference_ThrowsException() + { + Assert.That(() => AbstractValidatorExtensions.GetResult(null!, String.Empty, CancellationToken.None), Throws.ArgumentNullException); + } +}