Add project files.
This commit is contained in:
		
							
								
								
									
										25
									
								
								Lib.Architecture.BuildingBlocks.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Lib.Architecture.BuildingBlocks.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  |  | ||||||
|  | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||||
|  | # Visual Studio Version 17 | ||||||
|  | VisualStudioVersion = 17.8.34309.116 | ||||||
|  | MinimumVisualStudioVersion = 10.0.40219.1 | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lib.Architecture.BuildingBlocks", "Lib.Architecture.BuildingBlocks\Lib.Architecture.BuildingBlocks.csproj", "{FBB6B156-0EB5-4728-8B4D-7E761F7C7506}" | ||||||
|  | EndProject | ||||||
|  | Global | ||||||
|  | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
|  | 		Debug|Any CPU = Debug|Any CPU | ||||||
|  | 		Release|Any CPU = Release|Any CPU | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||||
|  | 		{FBB6B156-0EB5-4728-8B4D-7E761F7C7506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{FBB6B156-0EB5-4728-8B4D-7E761F7C7506}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{FBB6B156-0EB5-4728-8B4D-7E761F7C7506}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{FBB6B156-0EB5-4728-8B4D-7E761F7C7506}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(SolutionProperties) = preSolution | ||||||
|  | 		HideSolutionNode = FALSE | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||||
|  | 		SolutionGuid = {48281157-94C3-4A0A-B0A9-D9BB2A94DBA7} | ||||||
|  | 	EndGlobalSection | ||||||
|  | EndGlobal | ||||||
							
								
								
									
										34
									
								
								Lib.Architecture.BuildingBlocks/Application/CommandResult.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Lib.Architecture.BuildingBlocks/Application/CommandResult.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public class CommandResult : ICommandResult | ||||||
|  |     { | ||||||
|  |         public CommandResult() { } | ||||||
|  |         protected ActionResult ViewModelResult { get; set; } | ||||||
|  |         public bool Success { get; set; } | ||||||
|  |         public object Result { get; set; } | ||||||
|  |         public ActionResult ViewModel => ViewModelResult; | ||||||
|  |         public IReadOnlyCollection<Notification> Messages { get; set; } | ||||||
|  |  | ||||||
|  |         public CommandResult(bool success) | ||||||
|  |         { | ||||||
|  |             Success = success; | ||||||
|  |         } | ||||||
|  |         public CommandResult(bool success, IReadOnlyCollection<Notification> messages) | ||||||
|  |         { | ||||||
|  |             Success = success; | ||||||
|  |             Messages = messages; | ||||||
|  |         } | ||||||
|  |         public CommandResult(bool success, object result) | ||||||
|  |         { | ||||||
|  |             Result = result; | ||||||
|  |             Success = success; | ||||||
|  |         } | ||||||
|  |         public void ValidationErrors(IEnumerable<Notification> notifications) | ||||||
|  |         { | ||||||
|  |             ViewModelResult = new PreconditionFailedObjectResult(notifications); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								Lib.Architecture.BuildingBlocks/Application/QueryResult.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Lib.Architecture.BuildingBlocks/Application/QueryResult.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public class QueryResult : IQueryResult | ||||||
|  |     { | ||||||
|  |         public QueryResult() { } | ||||||
|  |         public QueryResult(bool success, IReadOnlyCollection<Notification> messages) | ||||||
|  |         { | ||||||
|  |             Success = success; | ||||||
|  |             Messages = messages; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public QueryResult(bool success, dynamic result) | ||||||
|  |         { | ||||||
|  |             Success = success; | ||||||
|  |             Result = result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool Success { get; set; } | ||||||
|  |         public dynamic Result { get; set; } | ||||||
|  |         public IReadOnlyCollection<Notification> Messages { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								Lib.Architecture.BuildingBlocks/Commands/ICommand.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Lib.Architecture.BuildingBlocks/Commands/ICommand.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface ICommand { bool Validate(); } | ||||||
|  |     public interface ICommandResult { } | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								Lib.Architecture.BuildingBlocks/Commands/ICommandHandler.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Lib.Architecture.BuildingBlocks/Commands/ICommandHandler.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | {  | ||||||
|  |     public interface ICommandHandler<Tin> where Tin : ICommand | ||||||
|  |     { | ||||||
|  |         ValueTask<ICommandResult> ExecuteAsync(Tin command, CancellationToken cancellationToken = default); | ||||||
|  |     } | ||||||
|  |     public interface IComponentHandler<in TIn> where TIn : ICommand | ||||||
|  |     { | ||||||
|  |         ValueTask ExecuteAsync(TIn command, CancellationToken cancellationToken = default); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     //out | ||||||
|  |     public interface IComponentHandler<in TIn, TOut> where TIn : ICommand | ||||||
|  |                                                      where TOut : class | ||||||
|  |     { | ||||||
|  |         ValueTask<ICommandResult> ExecuteAsync<TOut>(TIn command, CancellationToken cancellationToken = default); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IAggregateRoot | ||||||
|  |     { | ||||||
|  |         Guid Id { get; } | ||||||
|  |     } | ||||||
|  |     public interface IAggregateRoot<out TType> where TType : new() | ||||||
|  |     { | ||||||
|  |         TType Id { get; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IDomainEvent | ||||||
|  |     { | ||||||
|  |         DateTime OccorredOn { get; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IDomainEventPublisher<TEvent> where TEvent : IEvent | ||||||
|  |     { | ||||||
|  |         ValueTask Publish(TEvent @event, CancellationToken cancellationToken); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								Lib.Architecture.BuildingBlocks/Contracts/Events/IEvent.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Lib.Architecture.BuildingBlocks/Contracts/Events/IEvent.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IEvent | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IEventHandler<T> where T : IDomainEvent | ||||||
|  |     { | ||||||
|  |         ValueTask Execute(T @event, CancellationToken ctx); | ||||||
|  |     } | ||||||
|  |     public interface IEventHandler<TIn, TOut> where TIn : IDomainEvent where TOut : BaseEntity | ||||||
|  |     { | ||||||
|  |         ValueTask<TOut> Execute(TIn @event, CancellationToken ctx); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								Lib.Architecture.BuildingBlocks/Endpoints/BaseEndpoint.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Lib.Architecture.BuildingBlocks/Endpoints/BaseEndpoint.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Core.Blueprint.External | ||||||
|  | { | ||||||
|  |     public class BaseEndpoint | ||||||
|  |     { | ||||||
|  |         public string Url { get; set; } | ||||||
|  |         public Uri Uri { get; set; } | ||||||
|  |         public string Token { get; set; } | ||||||
|  |         public string APIKey { get; set; } | ||||||
|  |         public string APISecret { get; set; } | ||||||
|  |         public string APIName { get; set; } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |     public class AccessLog | ||||||
|  |     { | ||||||
|  |         private Guid CorrelationId { get; set; } = new Guid(); | ||||||
|  |         protected DateTime DateTime { get; set; } = DateTime.Now; | ||||||
|  |         protected string Method { get; set; } | ||||||
|  |         protected object Request { get; set; } | ||||||
|  |         protected string User { get; set; } | ||||||
|  |  | ||||||
|  |         public void GetCurrentMethodExecution() | ||||||
|  |         { | ||||||
|  |             var method = System.Reflection.MethodBase.GetCurrentMethod(); | ||||||
|  |  | ||||||
|  |             Method = string.Format("{0}.{1}({2})", | ||||||
|  |                           method.ReflectedType.FullName, method.Name, | ||||||
|  |                           string.Join(",", method.GetParameters(). | ||||||
|  |                           Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)). | ||||||
|  |                           ToArray())); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetCurrentRequestExecution(string request) | ||||||
|  |         { | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |         public void SetCurrentUserExecution(string user) | ||||||
|  |         { | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								Lib.Architecture.BuildingBlocks/Entity/BaseEntity.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Lib.Architecture.BuildingBlocks/Entity/BaseEntity.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | using FluentValidation; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public class BaseEntity<TValidator> : Notificator where TValidator : IValidator, new() | ||||||
|  |     { | ||||||
|  |         public virtual DateOnly Created { get; set; } | ||||||
|  |     } | ||||||
|  |     public class BaseEntity : Notificator | ||||||
|  |     { | ||||||
|  |         public virtual DateOnly Created { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								Lib.Architecture.BuildingBlocks/Entity/ValueObject.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Lib.Architecture.BuildingBlocks/Entity/ValueObject.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public abstract class ValueObject | ||||||
|  |     {    | ||||||
|  |         protected abstract IEnumerable<object> GetEqualityComponents(); | ||||||
|  |         public override bool Equals(object obj) | ||||||
|  |         { | ||||||
|  |  | ||||||
|  |             if (obj is null || obj.GetType() != GetType()) | ||||||
|  |                 return false; | ||||||
|  |  | ||||||
|  |             var other = (ValueObject)obj; | ||||||
|  |  | ||||||
|  |             return GetEqualityComponents().SequenceEqual(other.GetEqualityComponents()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override int GetHashCode() | ||||||
|  |         { | ||||||
|  |             return GetEqualityComponents() | ||||||
|  |                 .Select(x => x is not null ? x.GetHashCode() : 0) | ||||||
|  |                 .Aggregate((x, y) => x ^ y); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected static bool EqualOperator(ValueObject left, ValueObject right) | ||||||
|  |         { | ||||||
|  |             if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null)) | ||||||
|  |                 return false; | ||||||
|  |  | ||||||
|  |             return ReferenceEquals(left, right) || left.Equals(right); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected static bool NotEqualOperator(ValueObject left, ValueObject right) | ||||||
|  |         { | ||||||
|  |             return !(EqualOperator(left, right)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/implement-value-objects | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								Lib.Architecture.BuildingBlocks/Events/DomainEvents.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Lib.Architecture.BuildingBlocks/Events/DomainEvents.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     //Class For Create Domain Events | ||||||
|  |     public record DomainEvent<TEntity>(TEntity Entity) : IDomainEvent where TEntity : IEvent | ||||||
|  |     { | ||||||
|  |         public DateTime OccorredOn => DateTime.Now; | ||||||
|  |         public Guid CorrelationId { get; init; } = Guid.NewGuid(); | ||||||
|  |  | ||||||
|  |         public override string ToString() | ||||||
|  |         { | ||||||
|  |             return typeof(TEntity).Name; | ||||||
|  |         } | ||||||
|  |         internal ICollection<IDomainEvent> DomainEvents { get; } = new List<IDomainEvent>(); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										63
									
								
								Lib.Architecture.BuildingBlocks/Helpers/ApiResponseHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Lib.Architecture.BuildingBlocks/Helpers/ApiResponseHelper.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | using Newtonsoft.Json; | ||||||
|  | using Refit; | ||||||
|  | using System.Net; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Helpers | ||||||
|  | { | ||||||
|  |     public static class ApiResponseHelper | ||||||
|  |     { | ||||||
|  |         public static void EvaluatePort<TPort>(Exception exception, TPort port) | ||||||
|  |             where TPort : INotFoundPort, IBusinessErrorPort, ITimeoutPort, INoContentPort, | ||||||
|  |             IUnauthorizedPort, IForbiddenPort, IInternalServerErrorPort, IBadRequestPort | ||||||
|  |         { | ||||||
|  |             if (exception is ApiException refitException) | ||||||
|  |             { | ||||||
|  |                 dynamic? errorMessage = string.Empty; | ||||||
|  |  | ||||||
|  |                 if (!string.IsNullOrEmpty(refitException.Content)) | ||||||
|  |                 { | ||||||
|  |                     try | ||||||
|  |                     { | ||||||
|  |                         errorMessage = JsonConvert.DeserializeObject<string>(refitException.Content) ?? string.Empty; | ||||||
|  |                     } | ||||||
|  |                     catch (JsonException) | ||||||
|  |                     { | ||||||
|  |                         if (!string.IsNullOrEmpty(refitException.Content)) | ||||||
|  |                         { | ||||||
|  |                             errorMessage = JsonConvert.DeserializeObject<HttpError>(refitException.Content); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         if (errorMessage?.Error.Target is null) | ||||||
|  |                         { | ||||||
|  |                             errorMessage = Newtonsoft.Json.JsonConvert.DeserializeObject<GenericErrorResponse>(refitException.Content); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (refitException.StatusCode == HttpStatusCode.InternalServerError) | ||||||
|  |                     port.InternalServerError(errorMessage); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.NotFound) | ||||||
|  |                     port.NotFound(errorMessage); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.Forbidden && errorMessage) | ||||||
|  |                     port.Forbidden(errorMessage); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.UnprocessableContent) | ||||||
|  |                     port.BusinessError(errorMessage); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.BadRequest) | ||||||
|  |                     port.BadRequest(errorMessage); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.NoContent) | ||||||
|  |                     port.NoContentSuccess(); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.Unauthorized) | ||||||
|  |                     port.Unauthorized(); | ||||||
|  |  | ||||||
|  |                 else if (refitException.StatusCode == HttpStatusCode.Forbidden) | ||||||
|  |                     port.Forbidden(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | // *********************************************************************** | ||||||
|  | // <copyright file="AuthenticatedHttpClientHandler.cs"> | ||||||
|  | //     Heath | ||||||
|  | // </copyright> | ||||||
|  | // *********************************************************************** | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Helpers.Token | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Class to inject the token in all requests. | ||||||
|  |     /// </summary> | ||||||
|  |     public class AuthenticatedHttpClientHandler : DelegatingHandler | ||||||
|  |     { | ||||||
|  |         private readonly ITokenProvider _tokenProvider; | ||||||
|  |  | ||||||
|  |         public AuthenticatedHttpClientHandler(ITokenProvider tokenProvider) | ||||||
|  |         { | ||||||
|  |             _tokenProvider = tokenProvider; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | ||||||
|  |         { | ||||||
|  |             var token = _tokenProvider.GetToken(); | ||||||
|  |             if (!string.IsNullOrEmpty(token)) | ||||||
|  |             { | ||||||
|  |                 request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return await base.SendAsync(request, cancellationToken); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | // *********************************************************************** | ||||||
|  | // <copyright file="HttpContextTokenProvider.cs"> | ||||||
|  | //     Heath | ||||||
|  | // </copyright> | ||||||
|  | // *********************************************************************** | ||||||
|  |  | ||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Helpers.Token | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Class to return the access token to controllers. | ||||||
|  |     /// </summary> | ||||||
|  |     public class HttpContextTokenProvider : ITokenProvider | ||||||
|  |     { | ||||||
|  |         private readonly IHttpContextAccessor _httpContextAccessor; | ||||||
|  |  | ||||||
|  |         public HttpContextTokenProvider(IHttpContextAccessor httpContextAccessor) | ||||||
|  |         { | ||||||
|  |             _httpContextAccessor = httpContextAccessor; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Get token from headers. | ||||||
|  |         /// </summary> | ||||||
|  |         public string GetToken() | ||||||
|  |         { | ||||||
|  |             return _httpContextAccessor.HttpContext?.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | // *********************************************************************** | ||||||
|  | // <copyright file="ITokenProvider.cs"> | ||||||
|  | //     Heath | ||||||
|  | // </copyright> | ||||||
|  | // *********************************************************************** | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Helpers.Token | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Interface for token provider. | ||||||
|  |     /// </summary> | ||||||
|  |     public interface ITokenProvider | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// Get token from headers. | ||||||
|  |         /// </summary> | ||||||
|  |         string GetToken(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | <Project Sdk="Microsoft.NET.Sdk"> | ||||||
|  |  | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <TargetFramework>net8.0</TargetFramework> | ||||||
|  |     <ImplicitUsings>enable</ImplicitUsings> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|  |   </PropertyGroup> | ||||||
|  |  | ||||||
|  |   <ItemGroup> | ||||||
|  |     <PackageReference Include="Core.Blueprint.Mongo" Version="0.3.0-alpha0047" /> | ||||||
|  |     <PackageReference Include="FluentValidation" Version="11.11.0" /> | ||||||
|  |     <PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" /> | ||||||
|  |     <PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.11.0" /> | ||||||
|  |     <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.3.0" /> | ||||||
|  |     <PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" /> | ||||||
|  |     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||||
|  |     <PackageReference Include="Refit" Version="8.0.0" /> | ||||||
|  |     <PackageReference Include="System.Net.Http" Version="4.3.4" /> | ||||||
|  |     <PackageReference Include="System.Security.Cryptography.Xml" Version="9.0.1" /> | ||||||
|  |     <PackageReference Include="System.Text.Encodings.Web" Version="9.0.1" /> | ||||||
|  |     <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |  | ||||||
|  | </Project> | ||||||
							
								
								
									
										16
									
								
								Lib.Architecture.BuildingBlocks/Messages/Command.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Lib.Architecture.BuildingBlocks/Messages/Command.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  |  | ||||||
|  | using FluentValidation.Results; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public abstract class Command : Message | ||||||
|  |     { | ||||||
|  |         public DateTime Timestamp { get; private set; } | ||||||
|  |         public ValidationResult ValidationResult { get; set; } | ||||||
|  |  | ||||||
|  |         protected Command() | ||||||
|  |         { | ||||||
|  |             Timestamp = DateTime.Now; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								Lib.Architecture.BuildingBlocks/Messages/Event.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Lib.Architecture.BuildingBlocks/Messages/Event.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public abstract class Event : Message | ||||||
|  |     { | ||||||
|  |         public DateTime Timestamp { get; private set; } | ||||||
|  |  | ||||||
|  |         protected Event() | ||||||
|  |         { | ||||||
|  |             Timestamp = DateTime.Now; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								Lib.Architecture.BuildingBlocks/Messages/Message.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Lib.Architecture.BuildingBlocks/Messages/Message.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public abstract class Message: Notificator | ||||||
|  |     { | ||||||
|  |         public string Result { get; protected set; } | ||||||
|  |         public string MessageType { get; protected set; } | ||||||
|  |         public Guid AggregateId { get; protected set; } | ||||||
|  |  | ||||||
|  |         protected Message() | ||||||
|  |         { | ||||||
|  |             MessageType = GetType().Name; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.Infrastructure; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public sealed class BadGatewayError: ObjectResult | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status502BadGateway; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |  | ||||||
|  |         public BadGatewayError(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void GatherException(Exception exception) | ||||||
|  |         { | ||||||
|  |             if (exception is AggregateException) | ||||||
|  |             { | ||||||
|  |                 var agEx = exception as AggregateException; | ||||||
|  |                 Message = string.Join(" | ", agEx.InnerExceptions.Select(e => e.Message)); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Message = exception.Message; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public sealed class BadRequestError: ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status400BadRequest; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |  | ||||||
|  |         public BadRequestError(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void GatherException(Exception exception) | ||||||
|  |         { | ||||||
|  |             if (exception is AggregateException) | ||||||
|  |             { | ||||||
|  |                 var agEx = exception as AggregateException; | ||||||
|  |                 Message = string.Join(" | ", agEx.InnerExceptions.Select(e => e.Message)); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Message = exception.Message; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  |  | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public sealed class BusinessError | ||||||
|  |     { | ||||||
|  |         public string Key { get; set; } | ||||||
|  |         public string Message { get; set; } | ||||||
|  |  | ||||||
|  |         public BusinessError(string key, string message) | ||||||
|  |         { | ||||||
|  |             Key = key; | ||||||
|  |             Message = message; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BusinessError(Exception coreException, string key) | ||||||
|  |         { | ||||||
|  |             Key = key; | ||||||
|  |             Message = coreException.Message; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | // *********************************************************************** | ||||||
|  | // <copyright file="ErrorDetailsDto.cs"> | ||||||
|  | //     Heath | ||||||
|  | // </copyright> | ||||||
|  | // *********************************************************************** | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks; | ||||||
|  |  | ||||||
|  | /// <summary> | ||||||
|  | /// The service error details transfer object. | ||||||
|  | /// </summary> | ||||||
|  | public class ErrorDetails | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Gets or sets the service error code. | ||||||
|  |     /// </summary> | ||||||
|  |  | ||||||
|  |     public string? ErrorCode { get; set; } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Gets or sets the service error message. | ||||||
|  |     /// </summary> | ||||||
|  |     public string? Message { get; set; } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Gets or sets the service target. | ||||||
|  |     /// </summary> | ||||||
|  |     public string? Target { get; set; } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public sealed class GatewayTimeoutError: ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status504GatewayTimeout; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |  | ||||||
|  |         public GatewayTimeoutError(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void GatherException(Exception exception) | ||||||
|  |         { | ||||||
|  |             if (exception is AggregateException) | ||||||
|  |             { | ||||||
|  |                 var agEx = exception as AggregateException; | ||||||
|  |                 Message = string.Join(" | ", agEx.InnerExceptions.Select(e => e.Message)); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Message = exception.Message; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks; | ||||||
|  |  | ||||||
|  | public class GenericErrorResponse | ||||||
|  | { | ||||||
|  |     public string Type { get; set; } | ||||||
|  |     public string Title { get; set; } | ||||||
|  |     public int Status { get; set; } | ||||||
|  |     public Dictionary<string, List<string>> Errors { get; set; } | ||||||
|  |     public string TraceId { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | // *********************************************************************** | ||||||
|  | // <copyright file="HttpErrorDto.cs"> | ||||||
|  | //     Heath | ||||||
|  | // </copyright> | ||||||
|  | // *********************************************************************** | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks; | ||||||
|  |  | ||||||
|  | /// <summary> | ||||||
|  | /// The service HTTP error data transfer object. | ||||||
|  | /// </summary> | ||||||
|  | public class HttpError | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Gets or sets the error. | ||||||
|  |     /// </summary> | ||||||
|  |     public ErrorDetails Error { get; set; } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Creates a new instance of <see cref="HttpError{TMessage}"/> | ||||||
|  |     /// with custom parameters. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <param name="message">The HTTP error message.</param> | ||||||
|  |     /// <param name="errorCode">The HTTP error code.</param> | ||||||
|  |     /// <param name="target">The HTTP error target.</param> | ||||||
|  |     public HttpError( | ||||||
|  |         string? message, | ||||||
|  |         string? errorCode, | ||||||
|  |         string? target) | ||||||
|  |     { | ||||||
|  |         Error = new ErrorDetails | ||||||
|  |         { | ||||||
|  |             ErrorCode = errorCode, | ||||||
|  |             Message = message, | ||||||
|  |             Target = target, | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.Infrastructure; | ||||||
|  | using System; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  | using System.Linq; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public sealed class InternalServerError : ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status500InternalServerError; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |  | ||||||
|  |         public InternalServerError(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void GatherException(Exception exception) | ||||||
|  |         { | ||||||
|  |             if (exception is AggregateException) | ||||||
|  |             { | ||||||
|  |                 var agEx = exception as AggregateException; | ||||||
|  |                 Message = string.Join(" | ", agEx.InnerExceptions.Select(e => e.Message)); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 Message = exception.Message; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,88 @@ | |||||||
|  | using Core.Blueprint.Mongo; | ||||||
|  | using MongoDB.Bson; | ||||||
|  | using MongoDB.Bson.Serialization.Attributes; | ||||||
|  | using Newtonsoft.Json; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Adapters; | ||||||
|  |  | ||||||
|  | [CollectionAttributeName("GPSPoints")] | ||||||
|  | public class GPSPointAdapter : Document | ||||||
|  | { | ||||||
|  |     [BsonElement("features")] | ||||||
|  |     [JsonProperty("features")] | ||||||
|  |     public List<FeatureCollection> Features { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("timestamp")] | ||||||
|  |     [JsonProperty("timestamp")] | ||||||
|  |     public DateTime Timestamp { get; set; } | ||||||
|  | } | ||||||
|  | public class FeatureCollection | ||||||
|  | { | ||||||
|  |     [BsonElement("type")] | ||||||
|  |     [JsonProperty("type")] | ||||||
|  |     public string Type { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("geometry")] | ||||||
|  |     [JsonProperty("geometry")] | ||||||
|  |     public Geometry Geometry { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("properties")] | ||||||
|  |     [JsonProperty("properties")] | ||||||
|  |     public Properties Properties { get; set; } = null!; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class Properties | ||||||
|  | { | ||||||
|  |     [BsonElement("technicianId")] | ||||||
|  |     [BsonRepresentation(BsonType.ObjectId)] | ||||||
|  |     [JsonProperty("technicianId")] | ||||||
|  |     public string TechnicianId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("technicianName")] | ||||||
|  |     [JsonProperty("technicianName")] | ||||||
|  |     public string TechnicianName { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("sbuSurveyId")] | ||||||
|  |     [BsonRepresentation(BsonType.ObjectId)] | ||||||
|  |     [JsonProperty("sbuSurveyId")] | ||||||
|  |     public string SbuSurveyId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("sbuSurveyMapsheetId")] | ||||||
|  |     [BsonRepresentation(BsonType.ObjectId)] | ||||||
|  |     [JsonProperty("sbuSurveyMapsheetId")] | ||||||
|  |     public string SbuSurveyMapsheetId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("trailId")] | ||||||
|  |     [JsonProperty("trailId")] | ||||||
|  |     public string TrailId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("deviceSerialNumber")] | ||||||
|  |     [JsonProperty("deviceSerialNumber")] | ||||||
|  |     public string DeviceSerialNumber { get; set; } = null!; | ||||||
|  | } | ||||||
|  | public class Geometry | ||||||
|  | { | ||||||
|  |     [BsonElement("type")] | ||||||
|  |     [JsonProperty("type")] | ||||||
|  |     public string Type { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("coordinates")] | ||||||
|  |     [JsonProperty("coordinates")] | ||||||
|  |     public List<double> Coordinates { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("latitude")] | ||||||
|  |     [JsonProperty("latitude")] | ||||||
|  |     public double Latitude { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("longitude")] | ||||||
|  |     [JsonProperty("longitude")] | ||||||
|  |     public double Longitude { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("orientation")] | ||||||
|  |     [JsonProperty("orientation")] | ||||||
|  |     public double Orientation { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("accuracy")] | ||||||
|  |     [JsonProperty("accuracy")] | ||||||
|  |     public int Accuracy { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | using MongoDB.Bson.Serialization.Attributes; | ||||||
|  | using Newtonsoft.Json; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Adapters; | ||||||
|  |  | ||||||
|  | public class GeometryAdapter | ||||||
|  | { | ||||||
|  |     [BsonElement("type")] | ||||||
|  |     [JsonProperty("type")] | ||||||
|  |     public string Type { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("coordinates")] | ||||||
|  |     [JsonProperty("coordinates")] | ||||||
|  |     public List<double> Coordinates { get; set; } = null!; | ||||||
|  | } | ||||||
| @@ -0,0 +1,87 @@ | |||||||
|  | using Core.Blueprint.Mongo; | ||||||
|  | using MongoDB.Bson; | ||||||
|  | using MongoDB.Bson.Serialization.Attributes; | ||||||
|  | using Newtonsoft.Json; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Adapters; | ||||||
|  |  | ||||||
|  | [CollectionAttributeName("Mapsheets")] | ||||||
|  | public class MapsheetAdapter : Document | ||||||
|  | { | ||||||
|  |     [BsonElement("features")] | ||||||
|  |     [JsonProperty("features")] | ||||||
|  |     public List<MapsheetCollection>? Features { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("timestamp")] | ||||||
|  |     [JsonProperty("timestamp")] | ||||||
|  |     public DateTime Timestamp { get; set; } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class MapsheetTechnicians | ||||||
|  | { | ||||||
|  |     [BsonElement("technicianId")] | ||||||
|  |     [BsonRepresentation(BsonType.ObjectId)] | ||||||
|  |     [JsonProperty("technicianId")] | ||||||
|  |     public string TechnicianId { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("technicianName")] | ||||||
|  |     [JsonProperty("technicianName")] | ||||||
|  |     public string TechnicianName { get; set; } = null!; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class MapsheetProperties | ||||||
|  | { | ||||||
|  |     [BsonElement("surveyId")] | ||||||
|  |     [BsonRepresentation(BsonType.ObjectId)] | ||||||
|  |     [JsonProperty("surveyId")] | ||||||
|  |     public string SurveyId { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("mapsheetName")] | ||||||
|  |     [JsonProperty("mapsheetName")] | ||||||
|  |     public string MapsheetName { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("workOrderNumber")] | ||||||
|  |     [JsonProperty("workOrderNumber")] | ||||||
|  |     public string WorkOrderNumber { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("mapsheetStatus")] | ||||||
|  |     [BsonRepresentation(BsonType.String)] | ||||||
|  |     [JsonProperty("mapsheetStatus")] | ||||||
|  |     [System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))] | ||||||
|  |     public MapsheetStatus MapsheetStatus { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("footage")] | ||||||
|  |     [JsonProperty("footage")] | ||||||
|  |     public int Footage { get; set; } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | [System.Text.Json.Serialization.JsonConverter(typeof(JsonStringEnumConverter))] | ||||||
|  | public enum MapsheetStatus | ||||||
|  | { | ||||||
|  |     Ready = 1, | ||||||
|  |     InProgress = 2, | ||||||
|  |     Complete = 3, | ||||||
|  |     QaPending = 4, | ||||||
|  |     Closed = 5, | ||||||
|  |     Reopened = 6 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | public class MapsheetCollection | ||||||
|  | { | ||||||
|  |     [BsonElement("type")] | ||||||
|  |     [JsonProperty("type")] | ||||||
|  |     public string Type { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("mapsheetTechnicians")] | ||||||
|  |     [JsonProperty("mapsheetTechnicians")] | ||||||
|  |     public List<MapsheetTechnicians>? MapsheetTechnicians { get; set; } | ||||||
|  |  | ||||||
|  |     [BsonElement("geometry")] | ||||||
|  |     [JsonProperty("geometry")] | ||||||
|  |     public List<GeometryAdapter> Geometry { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("properties")] | ||||||
|  |     [JsonProperty("properties")] | ||||||
|  |     public MapsheetProperties? Properties { get; set; } | ||||||
|  | } | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | using Core.Blueprint.Mongo; | ||||||
|  | using MongoDB.Bson.Serialization.Attributes; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks.Adapters; | ||||||
|  |  | ||||||
|  | [CollectionAttributeName("Surveys")] | ||||||
|  | public class SurveyAdapter : Document | ||||||
|  | { | ||||||
|  |     [BsonElement("surveyName")] | ||||||
|  |     [JsonPropertyName("surveyName")] | ||||||
|  |     public string SurveyName { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("surveyType")] | ||||||
|  |     [JsonPropertyName("surveyType")] | ||||||
|  |     public string SurveyType { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("locations")] | ||||||
|  |     [JsonPropertyName("locations")] | ||||||
|  |     public List<string> Locations { get; set; } = []; | ||||||
|  |  | ||||||
|  |     [BsonElement("project")] | ||||||
|  |     [JsonPropertyName("project")] | ||||||
|  |     public string Project { get; set; } = null!; | ||||||
|  |  | ||||||
|  |     [BsonElement("surveyStatus")] | ||||||
|  |     [JsonPropertyName("surveyStatus")] | ||||||
|  |     public string SurveyStatus { get; set; } = null!; | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.Infrastructure; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [DefaultStatusCode(DefaultStatusCode)] | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public sealed class PreconditionFailedObjectResult : ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status412PreconditionFailed; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |         public PreconditionFailedObjectResult(object value) | ||||||
|  |             : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using Microsoft.AspNetCore.Mvc.Infrastructure; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [DefaultStatusCode(DefaultStatusCode)] | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public sealed class ServiceUnavaliableResult : ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status503ServiceUnavailable; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |         public ServiceUnavaliableResult(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | using Microsoft.AspNetCore.Http; | ||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public sealed class TimeoutServiceError : ObjectResult | ||||||
|  |     { | ||||||
|  |         private const int DefaultStatusCode = StatusCodes.Status504GatewayTimeout; | ||||||
|  |         public string Message { get; set; } = string.Empty; | ||||||
|  |         public TimeoutServiceError(object value) : base(value) | ||||||
|  |         { | ||||||
|  |             StatusCode = DefaultStatusCode; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,85 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public abstract class BasePresenter : IBusinessErrorPort, INoContentPort, INotFoundPort, | ||||||
|  |         IValidationErrorPort, ITimeoutPort, IServiceUnavaliablePort, IAcceptedPort, IForbiddenPort, | ||||||
|  |         IUnauthorizedPort, IInternalServerErrorPort, IBadRequestPort | ||||||
|  |     { | ||||||
|  |         public required IActionResult ViewModel { get; set; } | ||||||
|  |  | ||||||
|  |         public void BadRequest(string message) | ||||||
|  |         { | ||||||
|  |             ViewModel = new BadRequestError(message); | ||||||
|  |         } | ||||||
|  |         public void BadRequest(object message) | ||||||
|  |         { | ||||||
|  |             ViewModel = new BadRequestError(message); | ||||||
|  |         } | ||||||
|  |         public void BusinessError(string errorMessage) | ||||||
|  |         { | ||||||
|  |             ViewModel = new UnprocessableEntityObjectResult(errorMessage); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void NoContentSuccess() | ||||||
|  |         { | ||||||
|  |             ViewModel = new NoContentResult(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void NotFound() | ||||||
|  |         { | ||||||
|  |             ViewModel = new NotFoundResult(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void NotFound(object error) | ||||||
|  |         { | ||||||
|  |             ViewModel = new NotFoundObjectResult(error); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ValidationErrors(IEnumerable<Notification> notifications) | ||||||
|  |         { | ||||||
|  |             ViewModel = new PreconditionFailedObjectResult(notifications); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void TimeoutServiceError() | ||||||
|  |         { | ||||||
|  |             ViewModel = new TimeoutServiceError("Timeout Error"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ServiceUnavaiable(string errorMessage) | ||||||
|  |         { | ||||||
|  |             ViewModel = new ServiceUnavaliableResult(errorMessage); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Accepted() | ||||||
|  |         { | ||||||
|  |             ViewModel = new AcceptedResult(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ValidationError(string argument, string message) | ||||||
|  |         { | ||||||
|  |             var notification = new Notification(argument, message); | ||||||
|  |             ViewModel = new PreconditionFailedObjectResult(notification); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Unauthorized() | ||||||
|  |         { | ||||||
|  |             ViewModel = new UnauthorizedResult(); | ||||||
|  |         } | ||||||
|  |         public void Forbidden() | ||||||
|  |         { | ||||||
|  |             ViewModel = new ForbidResult(); | ||||||
|  |         } | ||||||
|  |         public void Forbidden(string message) | ||||||
|  |         { | ||||||
|  |             ViewModel = new ForbidResult(message); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void InternalServerError(object message) | ||||||
|  |         { | ||||||
|  |             ViewModel = new InternalServerError(message); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IAcceptedPort | ||||||
|  |     { | ||||||
|  |         void Accepted(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IBadRequestPort | ||||||
|  |     { | ||||||
|  |         void BadRequest(object message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | using Microsoft.AspNetCore.Mvc; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IBasePort | ||||||
|  |     { | ||||||
|  |         IActionResult ViewModel { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IBusinessErrorPort | ||||||
|  |     { | ||||||
|  |         void BusinessError(string errorMessage); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface ICreatedPort<in TCommand> where TCommand : class, new() | ||||||
|  |     { | ||||||
|  |         void Created(TCommand output); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IForbiddenPort | ||||||
|  |     { | ||||||
|  |         void Forbidden(); | ||||||
|  |         void Forbidden(string message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IInternalServerErrorPort | ||||||
|  |     { | ||||||
|  |         void InternalServerError(object message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface INoContentPort | ||||||
|  |     { | ||||||
|  |         void NoContentSuccess(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface INotFoundPort | ||||||
|  |     { | ||||||
|  |         void NotFound(); | ||||||
|  |         void NotFound(object error); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IServiceUnavaliablePort | ||||||
|  |     { | ||||||
|  |         void ServiceUnavaiable(string errorMessage); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								Lib.Architecture.BuildingBlocks/Presentation/ISuccessPort.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Lib.Architecture.BuildingBlocks/Presentation/ISuccessPort.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface ICommandSuccessPort<in TCommand> where TCommand : class, new() | ||||||
|  |     { | ||||||
|  |         void Success(TCommand output); | ||||||
|  |     } | ||||||
|  |     public interface IQuerySuccessPort<in TQuery> where TQuery : class, new() | ||||||
|  |     { | ||||||
|  |         void Success(TQuery output); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface ITimeoutPort | ||||||
|  |     { | ||||||
|  |         void TimeoutServiceError(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IUnauthorizedPort | ||||||
|  |     { | ||||||
|  |         void Unauthorized(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,9 @@ | |||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IValidationErrorPort | ||||||
|  |     { | ||||||
|  |         void ValidationError(string argument, string message); | ||||||
|  |         void ValidationErrors(IEnumerable<Notification> notifications); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,13 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IQueryHandler<in T> where T : IQuery | ||||||
|  |     { | ||||||
|  |         ValueTask<IQueryResult> ExecuteAsync(T query, CancellationToken cancellationToken = default); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								Lib.Architecture.BuildingBlocks/Queries/IQuery.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Lib.Architecture.BuildingBlocks/Queries/IQuery.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IQuery { bool Validate(); } | ||||||
|  |     public interface IQueryResult { } | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								Lib.Architecture.BuildingBlocks/RegisterBuildingBlocks.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Lib.Architecture.BuildingBlocks/RegisterBuildingBlocks.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | using FluentValidation; | ||||||
|  | using FluentValidation.AspNetCore; | ||||||
|  | using Microsoft.Extensions.DependencyInjection; | ||||||
|  | using Microsoft.Extensions.Options; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Text; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public static class RegisterBuildingBlocks | ||||||
|  |     { | ||||||
|  |         public static IServiceCollection AddBuildingBlocks(this IServiceCollection services) | ||||||
|  |         { | ||||||
|  |             services.AddScoped<ICommandResult, CommandResult>(); | ||||||
|  |             services.AddScoped<IQueryResult, QueryResult>(); | ||||||
|  |  | ||||||
|  |             return services; | ||||||
|  |         } | ||||||
|  |         public static IServiceCollection AddValidatorsFromNamespace(this IServiceCollection services, Assembly assembly, string @namespace) | ||||||
|  |         { | ||||||
|  |             var validators = assembly.GetTypes() | ||||||
|  |                 .Where(t => t.IsClass && !t.IsAbstract && t.IsPublic && t.Namespace == @namespace) | ||||||
|  |                 .Where(t => typeof(IValidator).IsAssignableFrom(t)) | ||||||
|  |                 .ToList(); | ||||||
|  |  | ||||||
|  |             foreach (var validator in validators) | ||||||
|  |             { | ||||||
|  |                 var interfaceType = validator.GetInterfaces() | ||||||
|  |                     .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IValidator<>)); | ||||||
|  |  | ||||||
|  |                 if (interfaceType != null) | ||||||
|  |                 { | ||||||
|  |                     services.AddTransient(interfaceType, validator); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return services; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								Lib.Architecture.BuildingBlocks/Utils/PrivateResolver.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Lib.Architecture.BuildingBlocks/Utils/PrivateResolver.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | using Newtonsoft.Json; | ||||||
|  | using Newtonsoft.Json.Serialization; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public class PrivateResolver : DefaultContractResolver | ||||||
|  |     { | ||||||
|  |         protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) | ||||||
|  |         { | ||||||
|  |             var prop = base.CreateProperty(member, memberSerialization); | ||||||
|  |             if (!prop.Writable) | ||||||
|  |             { | ||||||
|  |                 var property = member as PropertyInfo; | ||||||
|  |                 var hasPrivateSetter = property?.GetSetMethod(true) is not null; | ||||||
|  |                 prop.Writable = hasPrivateSetter; | ||||||
|  |             } | ||||||
|  |             return prop; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								Lib.Architecture.BuildingBlocks/Utils/TypeGetter.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Lib.Architecture.BuildingBlocks/Utils/TypeGetter.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public static class TypeGetter | ||||||
|  |     { | ||||||
|  |         public static Type? GetTypeFromCurrencDomainAssembly(string typeName) | ||||||
|  |         { | ||||||
|  |             return AppDomain.CurrentDomain.GetAssemblies() | ||||||
|  |                 .SelectMany(a => a.GetTypes() | ||||||
|  |                 .Where(x => x.FullName == typeName || x.Name == typeName)) | ||||||
|  |                 .FirstOrDefault(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | using FluentValidation; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IValidationHandler | ||||||
|  |     { | ||||||
|  |         bool ExecuteValidation<TV, TE>(TV validationObject, TE command) where TV : AbstractValidator<TE> where TE : Command; | ||||||
|  |     } | ||||||
|  |     //RuleFor | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface INotifier | ||||||
|  |     { | ||||||
|  |         IReadOnlyCollection<Notification> Notifications { get; } | ||||||
|  |         bool HasNotifications { get; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | using FluentValidation; | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     public interface IValidable | ||||||
|  |     { | ||||||
|  |         bool IsValid(IValidator validator); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public class Notification(string argument, string mensagem) | ||||||
|  |     { | ||||||
|  |         public string Argument { get; } = argument; | ||||||
|  |         public string Message { get; } = mensagem; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,80 @@ | |||||||
|  | using FluentValidation; | ||||||
|  | using FluentValidation.Results; | ||||||
|  | using System.Diagnostics.CodeAnalysis; | ||||||
|  | using static System.Runtime.InteropServices.JavaScript.JSType; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace Lib.Architecture.BuildingBlocks | ||||||
|  | { | ||||||
|  |     [ExcludeFromCodeCoverage] | ||||||
|  |     public abstract class Notificator : INotifier, IValidable | ||||||
|  |     { | ||||||
|  |         public bool HasNotifications => _notifications.Any(); | ||||||
|  |  | ||||||
|  |         //Notifications | ||||||
|  |         private readonly List<Notification> _notifications = []; | ||||||
|  |         public IReadOnlyCollection<Notification> Notifications => _notifications.AsReadOnly(); | ||||||
|  |  | ||||||
|  |         protected Notificator() | ||||||
|  |         { | ||||||
|  |            _notifications = []; | ||||||
|  |         } | ||||||
|  |         //Validation Results | ||||||
|  |         private ValidationResult _validationResult = new(); | ||||||
|  |         public ValidationResult GetValidationResult() => _validationResult; | ||||||
|  |         | ||||||
|  |         private readonly Dictionary<string, string> _errors = new(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public bool IsValid(IValidator validator) | ||||||
|  |         { | ||||||
|  |             var context = new ValidationContext<Notificator>(this); | ||||||
|  |  | ||||||
|  |             AddNotification(validator.Validate(context)); | ||||||
|  |  | ||||||
|  |             return !HasNotifications; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Validates the entity and adds series of notification to list of errors. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <typeparam name="TEntity"></typeparam> | ||||||
|  |         /// <param name="validator"></param> | ||||||
|  |         /// <param name="entity"></param> | ||||||
|  |         protected void AddNotification<TEntity>(AbstractValidator<TEntity> validator, TEntity entity) where TEntity : class | ||||||
|  |         { | ||||||
|  |             _validationResult = validator.Validate(entity); | ||||||
|  |  | ||||||
|  |             if (!_validationResult.IsValid) | ||||||
|  |             { | ||||||
|  |                 foreach (var item in _validationResult.Errors) | ||||||
|  |                 { | ||||||
|  |                     _errors.Add(item.ErrorMessage, item.ErrorCode); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Gets the object of validation and Adds Simple Notification to Validation Result | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="validation"></param> | ||||||
|  |         private void AddNotification(ValidationResult validation) | ||||||
|  |         { | ||||||
|  |             if (!validation.IsValid) | ||||||
|  |             { | ||||||
|  |                 foreach (var validationError in validation.Errors) | ||||||
|  |                 { | ||||||
|  |                     _notifications.Add(new Notification( | ||||||
|  |                         validationError.PropertyName, | ||||||
|  |                         validationError.ErrorMessage | ||||||
|  |                     )); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             return; | ||||||
|  |  | ||||||
|  |             | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 Sergio Matias Urquin
					Sergio Matias Urquin