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