From b010a7c35383a306caffad58941c34a299c62fe8 Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 17:53:59 -0300 Subject: [PATCH 01/12] add new internal model validator --- Lina.sln | 6 ++ .../Commons/BaseValidatorTest.cs | 29 ++++++++ Takasaki.Studio.Lina.Test/GlobalUsings.cs | 1 + .../Takasaki.Studio.Lina.Test.csproj | 23 +++++++ .../TakasakiStudio.Lina.AspNet.csproj | 2 +- ...Studio.Lina.AutoDependencyInjection.csproj | 2 +- .../BaseValidationRecord.cs | 43 ------------ TakasakiStudio.Lina.Common/BaseValidator.cs | 67 +++++++++++++++++++ .../Interfaces/IBaseValidate.cs | 44 ------------ .../LinaAbstractValidator.cs | 12 ++++ .../TakasakiStudio.Lina.Common.csproj | 2 +- .../Interfaces/IBaseEntity.cs | 19 ++++++ .../Interfaces/IBaseRepository.cs | 2 +- .../Models/BaseEntity.cs | 18 +---- .../Models/BaseEntityValidate.cs | 36 ++-------- .../Repositories/BaseRepository.cs | 2 +- .../TakasakiStudio.Lina.Utils.csproj | 2 +- .../TakasakiStudio.Lina.csproj | 2 +- 18 files changed, 171 insertions(+), 141 deletions(-) create mode 100644 Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs create mode 100644 Takasaki.Studio.Lina.Test/GlobalUsings.cs create mode 100644 Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj delete mode 100644 TakasakiStudio.Lina.Common/BaseValidationRecord.cs create mode 100644 TakasakiStudio.Lina.Common/BaseValidator.cs delete mode 100644 TakasakiStudio.Lina.Common/Interfaces/IBaseValidate.cs create mode 100644 TakasakiStudio.Lina.Common/LinaAbstractValidator.cs create mode 100644 TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs diff --git a/Lina.sln b/Lina.sln index d8e7772..d1d3a25 100644 --- a/Lina.sln +++ b/Lina.sln @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakasakiStudio.Lina.AutoDep EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakasakiStudio.Lina", "TakasakiStudio.Lina\TakasakiStudio.Lina.csproj", "{51F04308-2658-4EF5-AA3A-3126B77040C7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Takasaki.Studio.Lina.Test", "Takasaki.Studio.Lina.Test\Takasaki.Studio.Lina.Test.csproj", "{F368617F-1314-4AFB-A8F6-0103A48DA3E2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -42,5 +44,9 @@ Global {51F04308-2658-4EF5-AA3A-3126B77040C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {51F04308-2658-4EF5-AA3A-3126B77040C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {51F04308-2658-4EF5-AA3A-3126B77040C7}.Release|Any CPU.Build.0 = Release|Any CPU + {F368617F-1314-4AFB-A8F6-0103A48DA3E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F368617F-1314-4AFB-A8F6-0103A48DA3E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F368617F-1314-4AFB-A8F6-0103A48DA3E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F368617F-1314-4AFB-A8F6-0103A48DA3E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs b/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs new file mode 100644 index 0000000..fda1b7f --- /dev/null +++ b/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs @@ -0,0 +1,29 @@ +using TakasakiStudio.Lina.Common; +using FluentValidation; + +namespace Takasaki.Studio.Lina.Test.Commons; + +[TestClass] +public class BaseValidatorTest +{ + [TestMethod] + public async Task ValidateValidatorWorks() + { + var model = new ExampleModel + { + Test = string.Empty + }; + + Assert.IsFalse(await model.IsValid()); + } +} + +public class ExampleModel : BaseValidator +{ + public required string Test { get; set; } + + public override void SetupValidator(LinaAbstractValidator rules) + { + rules.RuleFor(x => x.Test).NotEmpty().NotNull(); + } +} \ No newline at end of file diff --git a/Takasaki.Studio.Lina.Test/GlobalUsings.cs b/Takasaki.Studio.Lina.Test/GlobalUsings.cs new file mode 100644 index 0000000..ab67c7e --- /dev/null +++ b/Takasaki.Studio.Lina.Test/GlobalUsings.cs @@ -0,0 +1 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj b/Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj new file mode 100644 index 0000000..80a8cfb --- /dev/null +++ b/Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + diff --git a/TakasakiStudio.Lina.AspNet/TakasakiStudio.Lina.AspNet.csproj b/TakasakiStudio.Lina.AspNet/TakasakiStudio.Lina.AspNet.csproj index 9177f02..8c1dddc 100644 --- a/TakasakiStudio.Lina.AspNet/TakasakiStudio.Lina.AspNet.csproj +++ b/TakasakiStudio.Lina.AspNet/TakasakiStudio.Lina.AspNet.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 2.0.13 + 2.1.0 true TakasakiStudio.Lina.AspNet TakasakiStudio diff --git a/TakasakiStudio.Lina.AutoDependencyInjection/TakasakiStudio.Lina.AutoDependencyInjection.csproj b/TakasakiStudio.Lina.AutoDependencyInjection/TakasakiStudio.Lina.AutoDependencyInjection.csproj index 1f77c68..5b567c3 100644 --- a/TakasakiStudio.Lina.AutoDependencyInjection/TakasakiStudio.Lina.AutoDependencyInjection.csproj +++ b/TakasakiStudio.Lina.AutoDependencyInjection/TakasakiStudio.Lina.AutoDependencyInjection.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 2.0.13 + 2.1.0 true TakasakiStudio.Lina.AutoDependencyInjection TakasakiStudio diff --git a/TakasakiStudio.Lina.Common/BaseValidationRecord.cs b/TakasakiStudio.Lina.Common/BaseValidationRecord.cs deleted file mode 100644 index 577e969..0000000 --- a/TakasakiStudio.Lina.Common/BaseValidationRecord.cs +++ /dev/null @@ -1,43 +0,0 @@ -using FluentValidation; -using FluentValidation.Results; -using TakasakiStudio.Lina.Common.Interfaces; - -namespace TakasakiStudio.Lina.Common; - -/// -/// Base class to view model with basic validation using Fluent Validation -/// -/// Self ref class -/// Validation class implementation -public abstract record BaseValidationRecord : IValidate, IBaseValidate -where TValidationClass : IValidator -{ - /// - /// Validate view model with class validation and throw exception if failure - /// - /// Failure validation information - public virtual async ValueTask Validate() - { - await GetBaseImplementationInstance().BaseValidate(); - } - - /// - /// Get validation errors - /// - /// Failure validation information - public virtual async Task GetErrors() - { - return await GetBaseImplementationInstance().BaseGetErrors(); - } - - /// - /// Verify if validation pass - /// - /// If valid - public virtual async ValueTask IsValid() - { - return await GetBaseImplementationInstance().BaseIsValid(); - } - - private IBaseValidate GetBaseImplementationInstance() => this; -} \ No newline at end of file diff --git a/TakasakiStudio.Lina.Common/BaseValidator.cs b/TakasakiStudio.Lina.Common/BaseValidator.cs new file mode 100644 index 0000000..d8203f2 --- /dev/null +++ b/TakasakiStudio.Lina.Common/BaseValidator.cs @@ -0,0 +1,67 @@ +using System.Reflection; +using FluentValidation; +using FluentValidation.Results; +using TakasakiStudio.Lina.Common.Interfaces; + +namespace TakasakiStudio.Lina.Common; + +/// +/// Base class to view model with basic validation using Fluent Validation +/// +/// Self ref class +public abstract class BaseValidator : IValidate +{ + private LinaAbstractValidator? _validator; + + protected BaseValidator() + { + InstanceValidator(); + } + + /// + /// Validate view model with class validation and throw exception if failure + /// + /// Failure validation information + public virtual async ValueTask Validate() + { + await _validator!.ValidateAndThrowAsync(GetClassInstance()); + } + + /// + /// Get validation errors + /// + /// Failure validation information + public virtual async Task GetErrors() + { + return await _validator!.ValidateAsync(GetClassInstance()); + } + + /// + /// Verify if validation pass + /// + /// If valid + public virtual async ValueTask IsValid() + { + return (await GetErrors()).IsValid; + } + + public abstract void SetupValidator(LinaAbstractValidator rules); + + private void InstanceValidator() + { + var setupValidator = (LinaAbstractValidator.ValidationBuilder)SetupValidator; + + _validator = (LinaAbstractValidator?)Activator.CreateInstance( + type: typeof(LinaAbstractValidator), + bindingAttr: BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, + binder: null, + args: [setupValidator], + culture: null, + activationAttributes: null); + } + + private TModel GetClassInstance() + { + return (TModel)(object)this; + } +} \ No newline at end of file diff --git a/TakasakiStudio.Lina.Common/Interfaces/IBaseValidate.cs b/TakasakiStudio.Lina.Common/Interfaces/IBaseValidate.cs deleted file mode 100644 index e90dcf4..0000000 --- a/TakasakiStudio.Lina.Common/Interfaces/IBaseValidate.cs +++ /dev/null @@ -1,44 +0,0 @@ -using FluentValidation; -using FluentValidation.Results; - -namespace TakasakiStudio.Lina.Common.Interfaces; - -/// -/// Base class with basic validation using Fluent Validation -/// -/// Self ref class -/// Validation class implementation -public interface IBaseValidate - where TValidationClass: IValidator -{ - private static IValidator GetValidationInstance() => - Activator.CreateInstance(); - - /// - /// Validate model with class validation and throw exception if failure - /// - /// Failure validation information - public async ValueTask BaseValidate() - { - await GetValidationInstance().ValidateAndThrowAsync((TModel)this); - } - - /// - /// Get validation errors - /// - /// Failure validation information - public async Task BaseGetErrors() - { - return await GetValidationInstance().ValidateAsync((TModel)this); - } - - /// - /// Verify if validation pass - /// - /// If valid - public async ValueTask BaseIsValid() - { - var resultValidation = await BaseGetErrors(); - return resultValidation.IsValid; - } -} \ No newline at end of file diff --git a/TakasakiStudio.Lina.Common/LinaAbstractValidator.cs b/TakasakiStudio.Lina.Common/LinaAbstractValidator.cs new file mode 100644 index 0000000..65dbb81 --- /dev/null +++ b/TakasakiStudio.Lina.Common/LinaAbstractValidator.cs @@ -0,0 +1,12 @@ +using FluentValidation; + +namespace TakasakiStudio.Lina.Common; + +public class LinaAbstractValidator : AbstractValidator +{ + public delegate void ValidationBuilder(LinaAbstractValidator builder); + internal LinaAbstractValidator(ValidationBuilder constructorBuilder) + { + constructorBuilder(this); + } +} \ No newline at end of file diff --git a/TakasakiStudio.Lina.Common/TakasakiStudio.Lina.Common.csproj b/TakasakiStudio.Lina.Common/TakasakiStudio.Lina.Common.csproj index acb770d..2f0ca65 100644 --- a/TakasakiStudio.Lina.Common/TakasakiStudio.Lina.Common.csproj +++ b/TakasakiStudio.Lina.Common/TakasakiStudio.Lina.Common.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 2.0.13 + 2.1.0 true TakasakiStudio.Lina.Common TakasakiStudio.Lina.Common diff --git a/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs b/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs new file mode 100644 index 0000000..e181a5f --- /dev/null +++ b/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs @@ -0,0 +1,19 @@ +namespace TakasakiStudio.Lina.Database.Interfaces; + +public interface IBaseEntity +{ + /// + /// Entity id + /// + public TPkType Id { get; set; } + + /// + /// Create a clone of value + /// + /// Value type + /// + public T Clone() + { + return (T)MemberwiseClone(); + } +} \ No newline at end of file diff --git a/TakasakiStudio.Lina.Database/Interfaces/IBaseRepository.cs b/TakasakiStudio.Lina.Database/Interfaces/IBaseRepository.cs index d24d4a6..cf42256 100644 --- a/TakasakiStudio.Lina.Database/Interfaces/IBaseRepository.cs +++ b/TakasakiStudio.Lina.Database/Interfaces/IBaseRepository.cs @@ -10,7 +10,7 @@ namespace TakasakiStudio.Lina.Database.Interfaces; /// Entity type /// Entity id type public interface IBaseRepository - where TEntity : BaseEntity + where TEntity : IBaseEntity { /// /// Base function for find by id diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntity.cs b/TakasakiStudio.Lina.Database/Models/BaseEntity.cs index 446f2bc..e5552f0 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntity.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseEntity.cs @@ -1,24 +1,12 @@ +using TakasakiStudio.Lina.Database.Interfaces; + namespace TakasakiStudio.Lina.Database.Models; /// /// Base entity database /// /// Entity id type -public abstract class BaseEntity +public abstract class BaseEntity : IBaseEntity { - /// - /// Entity id - /// public TPkType Id { get; set; } = default!; - - /// - /// Create a clone of value - /// - /// Value type - /// - public T Clone() - where T: BaseEntity - { - return (T)MemberwiseClone(); - } } \ No newline at end of file diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs b/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs index 34f0988..93a44b7 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs @@ -1,6 +1,8 @@ using FluentValidation; using FluentValidation.Results; +using TakasakiStudio.Lina.Common; using TakasakiStudio.Lina.Common.Interfaces; +using TakasakiStudio.Lina.Database.Interfaces; namespace TakasakiStudio.Lina.Database.Models; @@ -8,38 +10,8 @@ namespace TakasakiStudio.Lina.Database.Models; /// Base entity with validation /// /// Entity model -/// Entity model validation /// Entity id type -public abstract class BaseEntityValidate : BaseEntity, - IValidate, - IBaseValidate -where TValidationClass: IValidator +public abstract class BaseEntityValidate : BaseValidator, IBaseEntity { - /// - /// Validate entity and throw if invalid - /// - public virtual async ValueTask Validate() - { - await GetBaseImplementationInstance().BaseValidate(); - } - - /// - /// Get validation errors - /// - /// Errors - public virtual async Task GetErrors() - { - return await GetBaseImplementationInstance().BaseGetErrors(); - } - - /// - /// Entity is valid - /// - /// Is valid - public virtual async ValueTask IsValid() - { - return await GetBaseImplementationInstance().BaseIsValid(); - } - - private IBaseValidate GetBaseImplementationInstance() => this; + public TPkKey Id { get; set; } = default!; } \ No newline at end of file diff --git a/TakasakiStudio.Lina.Database/Repositories/BaseRepository.cs b/TakasakiStudio.Lina.Database/Repositories/BaseRepository.cs index ba924b8..c754c26 100644 --- a/TakasakiStudio.Lina.Database/Repositories/BaseRepository.cs +++ b/TakasakiStudio.Lina.Database/Repositories/BaseRepository.cs @@ -12,7 +12,7 @@ namespace TakasakiStudio.Lina.Database.Repositories; /// Entity /// Entity id public abstract class BaseRepository : IBaseRepository - where TEntity : BaseEntity + where TEntity : class, IBaseEntity { protected readonly DbContext DbContext; diff --git a/TakasakiStudio.Lina.Utils/TakasakiStudio.Lina.Utils.csproj b/TakasakiStudio.Lina.Utils/TakasakiStudio.Lina.Utils.csproj index 545d2d0..c6c61a3 100644 --- a/TakasakiStudio.Lina.Utils/TakasakiStudio.Lina.Utils.csproj +++ b/TakasakiStudio.Lina.Utils/TakasakiStudio.Lina.Utils.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 2.0.13 + 2.1.0 true TakasakiStudio.Lina.Utils TakasakiStudio.Lina.Utils diff --git a/TakasakiStudio.Lina/TakasakiStudio.Lina.csproj b/TakasakiStudio.Lina/TakasakiStudio.Lina.csproj index fe8c301..13be65d 100644 --- a/TakasakiStudio.Lina/TakasakiStudio.Lina.csproj +++ b/TakasakiStudio.Lina/TakasakiStudio.Lina.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 2.0.13 + 2.1.0 true TakasakiStudio.Lina TakasakiStudio.Lina From adf5cada1dbe92793908ba5e61802aaa9ad64716 Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 18:03:18 -0300 Subject: [PATCH 02/12] fix: "takasaki why do you need a reflection?" --- TakasakiStudio.Lina.Common/BaseValidator.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/TakasakiStudio.Lina.Common/BaseValidator.cs b/TakasakiStudio.Lina.Common/BaseValidator.cs index d8203f2..4da3a2a 100644 --- a/TakasakiStudio.Lina.Common/BaseValidator.cs +++ b/TakasakiStudio.Lina.Common/BaseValidator.cs @@ -1,4 +1,3 @@ -using System.Reflection; using FluentValidation; using FluentValidation.Results; using TakasakiStudio.Lina.Common.Interfaces; @@ -50,14 +49,7 @@ public virtual async ValueTask IsValid() private void InstanceValidator() { var setupValidator = (LinaAbstractValidator.ValidationBuilder)SetupValidator; - - _validator = (LinaAbstractValidator?)Activator.CreateInstance( - type: typeof(LinaAbstractValidator), - bindingAttr: BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, - binder: null, - args: [setupValidator], - culture: null, - activationAttributes: null); + _validator = new LinaAbstractValidator(setupValidator); } private TModel GetClassInstance() From 95e0518e823ccc7f380ea80c3e3e3581ad0106a7 Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 18:12:44 -0300 Subject: [PATCH 03/12] fix: public -> protected SetupValidator --- TakasakiStudio.Lina.Common/BaseValidator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TakasakiStudio.Lina.Common/BaseValidator.cs b/TakasakiStudio.Lina.Common/BaseValidator.cs index 4da3a2a..cf50cef 100644 --- a/TakasakiStudio.Lina.Common/BaseValidator.cs +++ b/TakasakiStudio.Lina.Common/BaseValidator.cs @@ -44,7 +44,7 @@ public virtual async ValueTask IsValid() return (await GetErrors()).IsValid; } - public abstract void SetupValidator(LinaAbstractValidator rules); + protected abstract void SetupValidator(LinaAbstractValidator rules); private void InstanceValidator() { From b5cf331c4eb3d365ce9039e36f5fd45f562d1942 Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 18:15:11 -0300 Subject: [PATCH 04/12] fix: test --- Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs b/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs index fda1b7f..829dde6 100644 --- a/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs +++ b/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs @@ -21,8 +21,8 @@ public async Task ValidateValidatorWorks() public class ExampleModel : BaseValidator { public required string Test { get; set; } - - public override void SetupValidator(LinaAbstractValidator rules) + + protected override void SetupValidator(LinaAbstractValidator rules) { rules.RuleFor(x => x.Test).NotEmpty().NotNull(); } From dc69a1d7b8331e3eac93478abeef3e05b986c83c Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 18:56:56 -0300 Subject: [PATCH 05/12] fix: test project name --- Lina.sln | 2 +- .../Commons/BaseValidatorTest.cs | 2 +- .../GlobalUsings.cs | 0 .../TakasakiStudio.Lina.Test.csproj | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {Takasaki.Studio.Lina.Test => TakasakiStudio.Lina.Test}/Commons/BaseValidatorTest.cs (92%) rename {Takasaki.Studio.Lina.Test => TakasakiStudio.Lina.Test}/GlobalUsings.cs (100%) rename Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj => TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj (100%) diff --git a/Lina.sln b/Lina.sln index d1d3a25..6754895 100644 --- a/Lina.sln +++ b/Lina.sln @@ -12,7 +12,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakasakiStudio.Lina.AutoDep EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakasakiStudio.Lina", "TakasakiStudio.Lina\TakasakiStudio.Lina.csproj", "{51F04308-2658-4EF5-AA3A-3126B77040C7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Takasaki.Studio.Lina.Test", "Takasaki.Studio.Lina.Test\Takasaki.Studio.Lina.Test.csproj", "{F368617F-1314-4AFB-A8F6-0103A48DA3E2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TakasakiStudio.Lina.Test", "TakasakiStudio.Lina.Test\TakasakiStudio.Lina.Test.csproj", "{F368617F-1314-4AFB-A8F6-0103A48DA3E2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs b/TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs similarity index 92% rename from Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs rename to TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs index 829dde6..ef7da60 100644 --- a/Takasaki.Studio.Lina.Test/Commons/BaseValidatorTest.cs +++ b/TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs @@ -1,7 +1,7 @@ using TakasakiStudio.Lina.Common; using FluentValidation; -namespace Takasaki.Studio.Lina.Test.Commons; +namespace TakasakiStudio.Lina.Test.Commons; [TestClass] public class BaseValidatorTest diff --git a/Takasaki.Studio.Lina.Test/GlobalUsings.cs b/TakasakiStudio.Lina.Test/GlobalUsings.cs similarity index 100% rename from Takasaki.Studio.Lina.Test/GlobalUsings.cs rename to TakasakiStudio.Lina.Test/GlobalUsings.cs diff --git a/Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj b/TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj similarity index 100% rename from Takasaki.Studio.Lina.Test/Takasaki.Studio.Lina.Test.csproj rename to TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj From 002ebf2f80d09c5fae0d4d91e33151dc46d38112 Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:32:06 -0300 Subject: [PATCH 06/12] update: Validator docs --- README.md | 56 +++++---------------- TakasakiStudio.Lina.Common/BaseValidator.cs | 18 +++++++ 2 files changed, 31 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 34326b9..e96b95e 100644 --- a/README.md +++ b/README.md @@ -163,36 +163,19 @@ await user.Validate(); Console.WriteLine("Valid"); -public class User : BaseEntityValidate +public class User : BaseValidator { public required string Name { get; set; } public required string Cpf { get; set; } public required string Cnpj { get; set; } -} - -public class UserValidation : AbstractValidator -{ - public UserValidation() - { - RuleFor(x => x.Name).NotEmpty(); - RuleFor(x => x.Cpf).ValidCpf(); - RuleFor(x => x.Cnpj).ValidCnpj(); - } -} - -public record UserViewModel(string Name, string Cpf, string Cnpj) - : BaseValidationRecord; - -public class UserViewModelValidation : AbstractValidator -{ - public UserViewModelValidation() + + protected override void SetupValidator(LinaAbstractValidator rules) { - RuleFor(x => x.Name).NotEmpty(); - RuleFor(x => x.Cpf).ValidCpf(); - RuleFor(x => x.Cnpj).ValidCnpj(); + rules.RuleFor(x => x.Name).NotEmpty(); + rules.RuleFor(x => x.Cpf).ValidCpf(); + rules.RuleFor(x => x.Cnpj).ValidCnpj(); } } -``` ## Dependency injection example usage @@ -225,9 +208,14 @@ public interface IAppConfig public string DatabaseUrl { get; } } -public class User : BaseValidateBaseEntity +public class User : BaseEntityValidate { public string Name { get; set; } = string.Empty; + + protected override void SetupValidator(LinaAbstractValidator rules) + { + rules.RuleFor(x => x.Name).NotEmpty(); + } public static implicit operator User(UserViewModel viewModel) { @@ -246,14 +234,6 @@ public class User : BaseValidateBaseEntity } } -public class UserValidation : AbstractValidator -{ - public UserValidation() - { - RuleFor(x => x.Name).NotEmpty(); - } -} - public class UserConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) @@ -264,19 +244,11 @@ public class UserConfiguration : IEntityTypeConfiguration } } -public record UserViewModel : BaseValidationRecord +public record UserViewModel { public string Name { get; set; } = string.Empty; } -public class UserViewModelValidation : AbstractValidator -{ - public UserViewModelValidation() - { - RuleFor(x => x.Name).NotEmpty(); - } -} - public interface IUserRepository : IBaseRepository { } @@ -305,8 +277,6 @@ public class UserService : IUserService public async Task Add(UserViewModel userViewModel) { - if (!await userViewModel.IsValid()) throw new Exception("Not valid"); - User user = userViewModel; await user.Validate(); diff --git a/TakasakiStudio.Lina.Common/BaseValidator.cs b/TakasakiStudio.Lina.Common/BaseValidator.cs index cf50cef..d73388e 100644 --- a/TakasakiStudio.Lina.Common/BaseValidator.cs +++ b/TakasakiStudio.Lina.Common/BaseValidator.cs @@ -44,6 +44,24 @@ public virtual async ValueTask IsValid() return (await GetErrors()).IsValid; } + /// + /// Setups the validator rules + /// + /// The validator instance, used to configure the validation rules + /// Fluent Validation documentation + /// + /// + /// public class ExampleModel : BaseValidator<ExampleModel> + /// { + /// public required string Test { get; set; } + /// + /// protected override void SetupValidator(LinaAbstractValidator<ExampleModel> rules) + /// { + /// rules.RuleFor(x => x.Test).NotEmpty().NotNull(); + /// } + /// } + /// + /// protected abstract void SetupValidator(LinaAbstractValidator rules); private void InstanceValidator() From 9894994ee958ffd7e63eb0511e02513b2529ee0a Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:34:33 -0300 Subject: [PATCH 07/12] refactor: BaseValidator -> BaseValidated --- README.md | 2 +- .../{BaseValidator.cs => BaseValidated.cs} | 6 +++--- TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs | 2 +- .../Commons/{BaseValidatorTest.cs => BaseValidatedTest.cs} | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename TakasakiStudio.Lina.Common/{BaseValidator.cs => BaseValidated.cs} (93%) rename TakasakiStudio.Lina.Test/Commons/{BaseValidatorTest.cs => BaseValidatedTest.cs} (86%) diff --git a/README.md b/README.md index e96b95e..566aed6 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ await user.Validate(); Console.WriteLine("Valid"); -public class User : BaseValidator +public class User : BaseValidated { public required string Name { get; set; } public required string Cpf { get; set; } diff --git a/TakasakiStudio.Lina.Common/BaseValidator.cs b/TakasakiStudio.Lina.Common/BaseValidated.cs similarity index 93% rename from TakasakiStudio.Lina.Common/BaseValidator.cs rename to TakasakiStudio.Lina.Common/BaseValidated.cs index d73388e..10b0905 100644 --- a/TakasakiStudio.Lina.Common/BaseValidator.cs +++ b/TakasakiStudio.Lina.Common/BaseValidated.cs @@ -8,11 +8,11 @@ namespace TakasakiStudio.Lina.Common; /// Base class to view model with basic validation using Fluent Validation /// /// Self ref class -public abstract class BaseValidator : IValidate +public abstract class BaseValidated : IValidate { private LinaAbstractValidator? _validator; - protected BaseValidator() + protected BaseValidated() { InstanceValidator(); } @@ -51,7 +51,7 @@ public virtual async ValueTask IsValid() /// Fluent Validation documentation /// /// - /// public class ExampleModel : BaseValidator<ExampleModel> + /// public class ExampleModel : BaseValidated<ExampleModel> /// { /// public required string Test { get; set; } /// diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs b/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs index 93a44b7..9f99a36 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs @@ -11,7 +11,7 @@ namespace TakasakiStudio.Lina.Database.Models; /// /// Entity model /// Entity id type -public abstract class BaseEntityValidate : BaseValidator, IBaseEntity +public abstract class BaseEntityValidate : BaseValidated, IBaseEntity { public TPkKey Id { get; set; } = default!; } \ No newline at end of file diff --git a/TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs b/TakasakiStudio.Lina.Test/Commons/BaseValidatedTest.cs similarity index 86% rename from TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs rename to TakasakiStudio.Lina.Test/Commons/BaseValidatedTest.cs index ef7da60..ca9bde6 100644 --- a/TakasakiStudio.Lina.Test/Commons/BaseValidatorTest.cs +++ b/TakasakiStudio.Lina.Test/Commons/BaseValidatedTest.cs @@ -4,7 +4,7 @@ namespace TakasakiStudio.Lina.Test.Commons; [TestClass] -public class BaseValidatorTest +public class BaseValidatedTest { [TestMethod] public async Task ValidateValidatorWorks() @@ -18,7 +18,7 @@ public async Task ValidateValidatorWorks() } } -public class ExampleModel : BaseValidator +public class ExampleModel : BaseValidated { public required string Test { get; set; } From 0fd30c95f45609fdf63889ab4d17fd165887182f Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:36:12 -0300 Subject: [PATCH 08/12] refacotr: BaseEntityValidate -> BaseEntityValidated --- README.md | 2 +- .../Models/{BaseEntityValidate.cs => BaseEntityValidated.cs} | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) rename TakasakiStudio.Lina.Database/Models/{BaseEntityValidate.cs => BaseEntityValidated.cs} (63%) diff --git a/README.md b/README.md index 566aed6..cfb661d 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ public interface IAppConfig public string DatabaseUrl { get; } } -public class User : BaseEntityValidate +public class User : BaseEntityValidated { public string Name { get; set; } = string.Empty; diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs b/TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs similarity index 63% rename from TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs rename to TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs index 9f99a36..bc3b7eb 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntityValidate.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs @@ -1,7 +1,4 @@ -using FluentValidation; -using FluentValidation.Results; using TakasakiStudio.Lina.Common; -using TakasakiStudio.Lina.Common.Interfaces; using TakasakiStudio.Lina.Database.Interfaces; namespace TakasakiStudio.Lina.Database.Models; @@ -11,7 +8,7 @@ namespace TakasakiStudio.Lina.Database.Models; /// /// Entity model /// Entity id type -public abstract class BaseEntityValidate : BaseValidated, IBaseEntity +public abstract class BaseEntityValidated : BaseValidated, IBaseEntity { public TPkKey Id { get; set; } = default!; } \ No newline at end of file From c8909533fec932e234bd65e3d03ae861fe3b75c5 Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:39:34 -0300 Subject: [PATCH 09/12] refactor: BaseEntityValidated -> BaseValidatedEntity --- README.md | 2 +- .../Models/{BaseEntityValidated.cs => BaseValidatedEntity.cs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename TakasakiStudio.Lina.Database/Models/{BaseEntityValidated.cs => BaseValidatedEntity.cs} (85%) diff --git a/README.md b/README.md index cfb661d..704493c 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ public interface IAppConfig public string DatabaseUrl { get; } } -public class User : BaseEntityValidated +public class User : BaseValidatedEntity { public string Name { get; set; } = string.Empty; diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs b/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs similarity index 85% rename from TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs rename to TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs index bc3b7eb..50efb63 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntityValidated.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs @@ -8,7 +8,7 @@ namespace TakasakiStudio.Lina.Database.Models; /// /// Entity model /// Entity id type -public abstract class BaseEntityValidated : BaseValidated, IBaseEntity +public abstract class BaseValidatedEntity : BaseValidated, IBaseEntity { public TPkKey Id { get; set; } = default!; } \ No newline at end of file From ff0d54eedd175ddedfb31998a67b4057764433a0 Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:39:59 -0300 Subject: [PATCH 10/12] update: deps --- .../TakasakiStudio.Lina.Test.csproj | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj b/TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj index 80a8cfb..e0bb648 100644 --- a/TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj +++ b/TakasakiStudio.Lina.Test/TakasakiStudio.Lina.Test.csproj @@ -10,10 +10,13 @@ - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + From d9882f5f3814db5544466f0cc0d17a6eb3158259 Mon Sep 17 00:00:00 2001 From: LuckShiba Date: Mon, 13 May 2024 19:58:51 -0300 Subject: [PATCH 11/12] fix: README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 704493c..6472394 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ public class User : BaseValidated rules.RuleFor(x => x.Cnpj).ValidCnpj(); } } +``` ## Dependency injection example usage From 325035031bcc28beffb7e7426ac78994bdeece64 Mon Sep 17 00:00:00 2001 From: Takasakiii Date: Mon, 13 May 2024 20:04:40 -0300 Subject: [PATCH 12/12] fix: "Why does a person who defends access level have access problems?" --- .../Interfaces/IBaseEntity.cs | 7 ++----- TakasakiStudio.Lina.Database/Models/BaseEntity.cs | 13 +++++++++++++ .../Models/BaseValidatedEntity.cs | 13 +++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs b/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs index e181a5f..d3f81da 100644 --- a/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs +++ b/TakasakiStudio.Lina.Database/Interfaces/IBaseEntity.cs @@ -6,14 +6,11 @@ public interface IBaseEntity /// Entity id /// public TPkType Id { get; set; } - + /// /// Create a clone of value /// /// Value type /// - public T Clone() - { - return (T)MemberwiseClone(); - } + public T Clone(); } \ No newline at end of file diff --git a/TakasakiStudio.Lina.Database/Models/BaseEntity.cs b/TakasakiStudio.Lina.Database/Models/BaseEntity.cs index e5552f0..ceede11 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseEntity.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseEntity.cs @@ -8,5 +8,18 @@ namespace TakasakiStudio.Lina.Database.Models; /// Entity id type public abstract class BaseEntity : IBaseEntity { + /// + /// Entity id + /// public TPkType Id { get; set; } = default!; + + /// + /// Create a clone of value + /// + /// Value type + /// + public T Clone() + { + return (T)MemberwiseClone(); + } } \ No newline at end of file diff --git a/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs b/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs index 50efb63..d8c1dc4 100644 --- a/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs +++ b/TakasakiStudio.Lina.Database/Models/BaseValidatedEntity.cs @@ -10,5 +10,18 @@ namespace TakasakiStudio.Lina.Database.Models; /// Entity id type public abstract class BaseValidatedEntity : BaseValidated, IBaseEntity { + /// + /// Entity id + /// public TPkKey Id { get; set; } = default!; + + /// + /// Create a clone of value + /// + /// Value type + /// + public T Clone() + { + return (T)MemberwiseClone(); + } } \ No newline at end of file