diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..de197596
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+charset = utf-8
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..254d1f38
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+* text=auto
+*.cs diff=csharp
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
new file mode 100644
index 00000000..88d3429e
--- /dev/null
+++ b/.github/workflows/publish.yaml
@@ -0,0 +1,26 @@
+name: publish
+on:
+ push:
+ branches: [main]
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: DotNet Setup
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: "9.x.x"
+ env:
+ NUGET_PACKAGES: ${{ runner.temp }}/nuget/packages
+
+ - name: DotNet Pack
+ run: find ./source -name '*.csproj' -exec dotnet pack {} --configuration Release --output packages \;
+
+ - name: DotNet NuGet Delete
+ run: curl -s https://azuresearch-usnc.nuget.org/query?q=owner:rafaelfgx | jq -r '.data[] | "dotnet nuget delete \(.id) \(.version) --non-interactive --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}"' | xargs -I {} bash -c "{}"
+
+ - name: DotNet NuGet Push
+ run: dotnet nuget push "packages/*.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate --no-symbols
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..0ab2e299
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+*.bat
+*.dll
+*.exe
+*.lib
+*.log
+*.pdb
+*.ps1
+*.suo
+*.tmp
+*.user
+*.userprefs
+*.vspx
+.vs
+[Bb]in
+[Dd]ebug
+[Ll]og
+[Oo]bj
+[Rr]elease
+[Rr]eleases
+[Tt]est[Rr]esults
diff --git a/license.md b/license.md
new file mode 100644
index 00000000..1f95d26c
--- /dev/null
+++ b/license.md
@@ -0,0 +1,5 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/readme.md b/readme.md
new file mode 100644
index 00000000..fd7a5912
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,41 @@
+# DotNetCore
+
+![](https://github.com/rafaelfgx/DotNetCore/actions/workflows/publish.yaml/badge.svg)
+
+.NET Nuget Packages.
+
+https://www.nuget.org/profiles/rafaelfgx
+
+## Documentation
+
+[AspNetCore](https://github.com/rafaelfgx/DotNetCore/tree/main/source/AspNetCore)
+
+[Domain](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Domain)
+
+[EntityFrameworkCore](https://github.com/rafaelfgx/DotNetCore/tree/main/source/EntityFrameworkCore)
+
+[Extensions](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Extensions)
+
+[IoC](https://github.com/rafaelfgx/DotNetCore/tree/main/source/IoC)
+
+[Logging](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Logging)
+
+[Mapping](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Mapping)
+
+[Mediator](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Mediator)
+
+[MongoDB](https://github.com/rafaelfgx/DotNetCore/tree/main/source/MongoDB)
+
+[Objects](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Objects)
+
+[RabbitMQ](https://github.com/rafaelfgx/DotNetCore/tree/main/source/RabbitMQ)
+
+[Repositories](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Repositories)
+
+[Results](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Results)
+
+[Security](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Security)
+
+[Services](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Services)
+
+[Validation](https://github.com/rafaelfgx/DotNetCore/tree/main/source/Validation)
diff --git a/source/AspNetCore/Attributes/EnumAuthorizeAttribute.cs b/source/AspNetCore/Attributes/EnumAuthorizeAttribute.cs
new file mode 100644
index 00000000..5b62b99f
--- /dev/null
+++ b/source/AspNetCore/Attributes/EnumAuthorizeAttribute.cs
@@ -0,0 +1,9 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace DotNetCore.AspNetCore;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
+public sealed class EnumAuthorizeAttribute : AuthorizeAttribute
+{
+ public EnumAuthorizeAttribute(params object[] roles) => Roles = string.Join(",", roles.Select(role => Enum.GetName(role.GetType(), role)));
+}
diff --git a/source/AspNetCore/DotNetCore.AspNetCore.csproj b/source/AspNetCore/DotNetCore.AspNetCore.csproj
new file mode 100644
index 00000000..ad4fa8f2
--- /dev/null
+++ b/source/AspNetCore/DotNetCore.AspNetCore.csproj
@@ -0,0 +1,18 @@
+
+
+ DotNetCore.AspNetCore
+ DotNetCore.AspNetCore
+ DotNetCore.AspNetCore
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/AspNetCore
+ AspNetCore, Attribute, Attributes, IApplicationBuilder, ApplicationBuilder, IHostBuilder, HostBuilder, HttpRequest, IServiceCollection, ServiceCollection, Result, Results, IActionResult, ActionResult
+ DotNetCore.AspNetCore
+
+
+
+
+
+
+
+
+
+
diff --git a/source/AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/source/AspNetCore/Extensions/ApplicationBuilderExtensions.cs
new file mode 100644
index 00000000..69ad9ee2
--- /dev/null
+++ b/source/AspNetCore/Extensions/ApplicationBuilderExtensions.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace DotNetCore.AspNetCore;
+
+public static class ApplicationBuilderExtensions
+{
+ public static void UseCorsAllowAny(this IApplicationBuilder application) => application.UseCors("AllowAny");
+
+ public static void UseException(this IApplicationBuilder application)
+ {
+ var environment = application.ApplicationServices.GetRequiredService();
+
+ if (environment.IsDevelopment()) application.UseDeveloperExceptionPage();
+ }
+
+ public static void UseLocalization(this IApplicationBuilder application, params string[] cultures) => application.UseRequestLocalization(options => options.AddSupportedCultures(cultures).AddSupportedUICultures(cultures).SetDefaultCulture(cultures.First()));
+}
diff --git a/source/AspNetCore/Extensions/BinaryFileExtensions.cs b/source/AspNetCore/Extensions/BinaryFileExtensions.cs
new file mode 100644
index 00000000..ff60d3d3
--- /dev/null
+++ b/source/AspNetCore/Extensions/BinaryFileExtensions.cs
@@ -0,0 +1,21 @@
+using DotNetCore.Objects;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.StaticFiles;
+
+namespace DotNetCore.AspNetCore;
+
+public static class BinaryFileExtensions
+{
+ public static IActionResult FileResult(this Task binaryFile)
+ {
+ if (binaryFile is null) return new NotFoundResult();
+
+ var file = binaryFile.Result;
+
+ if (file is null) return new NotFoundResult();
+
+ new FileExtensionContentTypeProvider().TryGetContentType(file.ContentType, out var contentType);
+
+ return contentType is null ? new NotFoundResult() : new FileContentResult(file.Bytes, contentType) { FileDownloadName = file.Name };
+ }
+}
diff --git a/source/AspNetCore/Extensions/HttpRequestExtensions.cs b/source/AspNetCore/Extensions/HttpRequestExtensions.cs
new file mode 100644
index 00000000..f223b9fc
--- /dev/null
+++ b/source/AspNetCore/Extensions/HttpRequestExtensions.cs
@@ -0,0 +1,23 @@
+using DotNetCore.Objects;
+using Microsoft.AspNetCore.Http;
+
+namespace DotNetCore.AspNetCore;
+
+public static class HttpRequestExtensions
+{
+ public static IList Files(this HttpRequest request)
+ {
+ var files = new List();
+
+ foreach (var file in request.Form.Files)
+ {
+ using var memoryStream = new MemoryStream();
+
+ file.CopyTo(memoryStream);
+
+ files.Add(new BinaryFile(Guid.NewGuid(), file.Name, memoryStream.ToArray(), file.Length, file.ContentType));
+ }
+
+ return files;
+ }
+}
diff --git a/source/AspNetCore/Extensions/JsonStringBoolConverter.cs b/source/AspNetCore/Extensions/JsonStringBoolConverter.cs
new file mode 100644
index 00000000..66657575
--- /dev/null
+++ b/source/AspNetCore/Extensions/JsonStringBoolConverter.cs
@@ -0,0 +1,11 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace DotNetCore.AspNetCore;
+
+public class JsonStringBoolConverter : JsonConverter
+{
+ public override bool Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => bool.TryParse(reader.GetString(), out var result) && result;
+
+ public override void Write(Utf8JsonWriter writer, bool value, JsonSerializerOptions options) => writer.WriteBooleanValue(value);
+}
diff --git a/source/AspNetCore/Extensions/ResultExtensions.cs b/source/AspNetCore/Extensions/ResultExtensions.cs
new file mode 100644
index 00000000..263e9e20
--- /dev/null
+++ b/source/AspNetCore/Extensions/ResultExtensions.cs
@@ -0,0 +1,19 @@
+using DotNetCore.Results;
+using Microsoft.AspNetCore.Mvc;
+
+namespace DotNetCore.AspNetCore;
+
+public static class ResultExtensions
+{
+ public static IActionResult ApiResult(this Result result) => new ObjectResult(result.HasMessage ? result.Message : result.Value) { StatusCode = (int)result.Status };
+
+ public static IActionResult ApiResult(this Task> result) => ApiResult(result.Result);
+
+ public static IActionResult ApiResult(this Result result) => new ObjectResult(result.Message) { StatusCode = (int)result.Status };
+
+ public static IActionResult ApiResult(this Task result) => ApiResult(result.Result);
+
+ public static IActionResult ApiResult(this T result) => new ObjectResult(result);
+
+ public static IActionResult ApiResult(this Task result) => ApiResult(result.Result);
+}
diff --git a/source/AspNetCore/Extensions/ServiceCollectionExtensions.cs b/source/AspNetCore/Extensions/ServiceCollectionExtensions.cs
new file mode 100644
index 00000000..71438628
--- /dev/null
+++ b/source/AspNetCore/Extensions/ServiceCollectionExtensions.cs
@@ -0,0 +1,63 @@
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.AspNetCore.Mvc.Authorization;
+using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.OpenApi.Models;
+using Swashbuckle.AspNetCore.SwaggerGen;
+using System.Text.Json.Serialization;
+
+namespace DotNetCore.AspNetCore;
+
+public static class ServiceCollectionExtensions
+{
+ public static IMvcBuilder AddAuthorizationPolicy(this IMvcBuilder builder) => builder.AddMvcOptions(options => options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build())));
+
+ public static IServiceCollection AddCorsAllowAny(this IServiceCollection services) => services.AddCors(options => options.AddPolicy("AllowAny", policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
+
+ public static IServiceCollection AddFileExtensionContentTypeProvider(this IServiceCollection services) => services.AddSingleton();
+
+ public static IMvcBuilder AddJsonOptions(this IMvcBuilder builder) => builder.AddJsonOptions(options =>
+ {
+ options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
+ options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
+ options.JsonSerializerOptions.Converters.Add(new JsonStringBoolConverter());
+ });
+
+ public static void AddSwaggerDefault(this IServiceCollection services) => services.AddSwaggerGen(ConfigureSwaggerGenOptions);
+
+ public static IServiceCollection ConfigureFormOptionsMaxLengthLimit(this IServiceCollection services) => services.Configure(options =>
+ {
+ options.ValueLengthLimit = int.MaxValue;
+ options.MultipartBodyLengthLimit = int.MaxValue;
+ });
+
+ private static void ConfigureSwaggerGenOptions(this SwaggerGenOptions options)
+ {
+ options.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
+ {
+ Type = SecuritySchemeType.ApiKey,
+ In = ParameterLocation.Header,
+ Name = "Authorization"
+ });
+
+ options.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = JwtBearerDefaults.AuthenticationScheme
+ },
+ In = ParameterLocation.Header,
+ Scheme = SecuritySchemeType.OAuth2.ToString(),
+ Name = JwtBearerDefaults.AuthenticationScheme
+ },
+ new List()
+ }
+ });
+ }
+}
diff --git a/source/AspNetCore/readme.md b/source/AspNetCore/readme.md
new file mode 100644
index 00000000..eedd7d74
--- /dev/null
+++ b/source/AspNetCore/readme.md
@@ -0,0 +1,86 @@
+# DotNetCore.AspNetCore
+
+## Attributes
+
+### EnumAuthorizeAttribute
+
+```cs
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
+public sealed class EnumAuthorizeAttribute : AuthorizeAttribute
+{
+ public EnumAuthorizeAttribute(params object[] roles) { }
+}
+```
+
+## Extensions
+
+### ApplicationBuilderExtensions
+
+```cs
+public static class ApplicationBuilderExtensions
+{
+ public static void UseCorsAllowAny(this IApplicationBuilder application) { }
+
+ public static void UseException(this IApplicationBuilder application) { }
+
+ public static void UseLocalization(this IApplicationBuilder application, params string[] cultures) { }
+
+ public static void ConfigureFormOptions(this IServiceCollection services) { }
+}
+```
+
+### BinaryFileExtensions
+
+```cs
+public static class BinaryFileExtensions
+{
+ public static IActionResult FileResult(this Task binaryFile) { }
+}
+```
+
+### HttpRequestExtensions
+
+```cs
+public static class HttpRequestExtensions
+{
+ public static IList Files(this HttpRequest request) { }
+}
+```
+
+### ResultExtensions
+
+```cs
+public static class ResultExtensions
+{
+ public static IActionResult ApiResult(this Result result) { }
+
+ public static IActionResult ApiResult(this Task> result) { }
+
+ public static IActionResult ApiResult(this Result result) { }
+
+ public static IActionResult ApiResult(this Task result) { }
+
+ public static IActionResult ApiResult(this T result) { }
+
+ public static IActionResult ApiResult(this Task result) { }
+}
+```
+
+### ServiceCollectionExtensions
+
+```cs
+public static class ServiceCollectionExtensions
+{
+ public static IMvcBuilder AddAuthorizationPolicy(this IMvcBuilder builder) { }
+
+ public static IServiceCollection AddCorsAllowAny(this IServiceCollection services) { }
+
+ public static IServiceCollection AddFileExtensionContentTypeProvider(this IServiceCollection services) { }
+
+ public static IMvcBuilder AddJsonOptions(this IMvcBuilder builder) { }
+
+ public static void AddSwaggerDefault(this IServiceCollection services) { }
+
+ public static IServiceCollection ConfigureFormOptionsMaxLengthLimit(this IServiceCollection services) { }
+}
+```
diff --git a/source/Directory.Build.props b/source/Directory.Build.props
new file mode 100644
index 00000000..66c19caf
--- /dev/null
+++ b/source/Directory.Build.props
@@ -0,0 +1,23 @@
+
+
+ true
+ true
+ true
+ false
+ enable
+ true
+ latest
+ en
+ MIT
+ readme.md
+ true
+ git
+ https://github.com/rafaelfgx/DotNetCore
+ snupkg
+ net9.0
+ 19.7.0
+
+
+
+
+
diff --git a/source/Directory.Packages.props b/source/Directory.Packages.props
new file mode 100644
index 00000000..857cec75
--- /dev/null
+++ b/source/Directory.Packages.props
@@ -0,0 +1,34 @@
+
+
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/Domain/DotNetCore.Domain.csproj b/source/Domain/DotNetCore.Domain.csproj
new file mode 100644
index 00000000..d9e9cc7c
--- /dev/null
+++ b/source/Domain/DotNetCore.Domain.csproj
@@ -0,0 +1,10 @@
+
+
+ DotNetCore.Domain
+ DotNetCore.Domain
+ DotNetCore.Domain
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/Domain
+ Domain, DDD, DomainDrivenDesign, Entity, Event, ValueObject
+ DotNetCore.Domain
+
+
diff --git a/source/Domain/Entity.cs b/source/Domain/Entity.cs
new file mode 100644
index 00000000..c8c0c1b0
--- /dev/null
+++ b/source/Domain/Entity.cs
@@ -0,0 +1,14 @@
+namespace DotNetCore.Domain;
+
+public abstract class Entity
+{
+ public long Id { get; init; }
+
+ public static bool operator !=(Entity left, Entity right) => !(left == right);
+
+ public static bool operator ==(Entity left, Entity right) => left?.Equals(right) == true;
+
+ public override bool Equals(object obj) => obj is Entity entity && (ReferenceEquals(this, entity) || Id == entity.Id);
+
+ public override int GetHashCode() => Id.GetHashCode();
+}
diff --git a/source/Domain/Event.cs b/source/Domain/Event.cs
new file mode 100644
index 00000000..f9db1243
--- /dev/null
+++ b/source/Domain/Event.cs
@@ -0,0 +1,8 @@
+namespace DotNetCore.Domain;
+
+public abstract class Event
+{
+ public Guid Id { get; } = Guid.NewGuid();
+
+ public DateTime DateTime { get; } = DateTime.UtcNow;
+}
diff --git a/source/Domain/readme.md b/source/Domain/readme.md
new file mode 100644
index 00000000..563f8bed
--- /dev/null
+++ b/source/Domain/readme.md
@@ -0,0 +1,29 @@
+# DotNetCore.Domain
+
+## Entity
+
+```cs
+public abstract class Entity
+{
+ public long Id { get; init; }
+
+ public static bool operator !=(Entity left, Entity right) { }
+
+ public static bool operator ==(Entity left, Entity right) { }
+
+ public override bool Equals(object obj) { }
+
+ public override int GetHashCode() { }
+}
+```
+
+## Event
+
+```cs
+public abstract class Event
+{
+ public Guid Id { get; } = Guid.NewGuid();
+
+ public DateTime DateTime { get; } = DateTime.UtcNow;
+}
+```
diff --git a/source/DotNetCore.sln b/source/DotNetCore.sln
new file mode 100644
index 00000000..839a1b40
--- /dev/null
+++ b/source/DotNetCore.sln
@@ -0,0 +1,115 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.2.32616.157
+MinimumVisualStudioVersion = 17.2.32616.157
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.AspNetCore", "AspNetCore\DotNetCore.AspNetCore.csproj", "{9B2E66F2-CD32-4A9B-BA3E-B887F5442D72}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Domain", "Domain\DotNetCore.Domain.csproj", "{D766DABA-B946-46E9-AB9D-669C88C2A09E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.EntityFrameworkCore", "EntityFrameworkCore\DotNetCore.EntityFrameworkCore.csproj", "{B7D1B18B-4986-4023-ADDF-8778D56017E0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Extensions", "Extensions\DotNetCore.Extensions.csproj", "{831B7F04-AACC-45EF-B767-E0F6AD50A824}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.IoC", "IoC\DotNetCore.IoC.csproj", "{38D5FB7D-C85B-44C5-925A-0741690F7EA9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Logging", "Logging\DotNetCore.Logging.csproj", "{2E0C3E42-4ED9-422B-8868-61A9F4C8CE75}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Mapping", "Mapping\DotNetCore.Mapping.csproj", "{49F742BC-CE56-410F-9B46-65900F0C012B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Mediator", "Mediator\DotNetCore.Mediator.csproj", "{01EB312A-E67D-4E9C-A159-16945153494E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.MongoDB", "MongoDB\DotNetCore.MongoDB.csproj", "{F1B9AE78-77EA-481C-92FE-562C1C529C38}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Objects", "Objects\DotNetCore.Objects.csproj", "{04D0F3BD-E7F5-4A5B-8B88-DE780CCC5AD7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.RabbitMQ", "RabbitMQ\DotNetCore.RabbitMQ.csproj", "{7977E46D-F4E4-4B48-9573-532064247265}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Repositories", "Repositories\DotNetCore.Repositories.csproj", "{43F95A55-0C4A-4AB5-A4EF-CC94F5CE55C7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Results", "Results\DotNetCore.Results.csproj", "{99249542-E7AF-45F1-AD1E-16398B3127BF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Security", "Security\DotNetCore.Security.csproj", "{FCD0B4F0-32DD-44B9-8899-556F5DAE8AA6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Services", "Services\DotNetCore.Services.csproj", "{CA2254AE-87E5-4402-816A-E3DE1F024693}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.Validation", "Validation\DotNetCore.Validation.csproj", "{FF02D406-2CA7-4D5A-979A-3694E2882C8C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9B2E66F2-CD32-4A9B-BA3E-B887F5442D72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9B2E66F2-CD32-4A9B-BA3E-B887F5442D72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9B2E66F2-CD32-4A9B-BA3E-B887F5442D72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9B2E66F2-CD32-4A9B-BA3E-B887F5442D72}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D766DABA-B946-46E9-AB9D-669C88C2A09E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D766DABA-B946-46E9-AB9D-669C88C2A09E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D766DABA-B946-46E9-AB9D-669C88C2A09E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D766DABA-B946-46E9-AB9D-669C88C2A09E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B7D1B18B-4986-4023-ADDF-8778D56017E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B7D1B18B-4986-4023-ADDF-8778D56017E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B7D1B18B-4986-4023-ADDF-8778D56017E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B7D1B18B-4986-4023-ADDF-8778D56017E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {831B7F04-AACC-45EF-B767-E0F6AD50A824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {831B7F04-AACC-45EF-B767-E0F6AD50A824}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {831B7F04-AACC-45EF-B767-E0F6AD50A824}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {831B7F04-AACC-45EF-B767-E0F6AD50A824}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38D5FB7D-C85B-44C5-925A-0741690F7EA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38D5FB7D-C85B-44C5-925A-0741690F7EA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38D5FB7D-C85B-44C5-925A-0741690F7EA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38D5FB7D-C85B-44C5-925A-0741690F7EA9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E0C3E42-4ED9-422B-8868-61A9F4C8CE75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E0C3E42-4ED9-422B-8868-61A9F4C8CE75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E0C3E42-4ED9-422B-8868-61A9F4C8CE75}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E0C3E42-4ED9-422B-8868-61A9F4C8CE75}.Release|Any CPU.Build.0 = Release|Any CPU
+ {49F742BC-CE56-410F-9B46-65900F0C012B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {49F742BC-CE56-410F-9B46-65900F0C012B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {49F742BC-CE56-410F-9B46-65900F0C012B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {49F742BC-CE56-410F-9B46-65900F0C012B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {01EB312A-E67D-4E9C-A159-16945153494E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {01EB312A-E67D-4E9C-A159-16945153494E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {01EB312A-E67D-4E9C-A159-16945153494E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {01EB312A-E67D-4E9C-A159-16945153494E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F1B9AE78-77EA-481C-92FE-562C1C529C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1B9AE78-77EA-481C-92FE-562C1C529C38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1B9AE78-77EA-481C-92FE-562C1C529C38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1B9AE78-77EA-481C-92FE-562C1C529C38}.Release|Any CPU.Build.0 = Release|Any CPU
+ {04D0F3BD-E7F5-4A5B-8B88-DE780CCC5AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {04D0F3BD-E7F5-4A5B-8B88-DE780CCC5AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {04D0F3BD-E7F5-4A5B-8B88-DE780CCC5AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {04D0F3BD-E7F5-4A5B-8B88-DE780CCC5AD7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7977E46D-F4E4-4B48-9573-532064247265}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7977E46D-F4E4-4B48-9573-532064247265}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7977E46D-F4E4-4B48-9573-532064247265}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7977E46D-F4E4-4B48-9573-532064247265}.Release|Any CPU.Build.0 = Release|Any CPU
+ {43F95A55-0C4A-4AB5-A4EF-CC94F5CE55C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {43F95A55-0C4A-4AB5-A4EF-CC94F5CE55C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {43F95A55-0C4A-4AB5-A4EF-CC94F5CE55C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {43F95A55-0C4A-4AB5-A4EF-CC94F5CE55C7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99249542-E7AF-45F1-AD1E-16398B3127BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99249542-E7AF-45F1-AD1E-16398B3127BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99249542-E7AF-45F1-AD1E-16398B3127BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99249542-E7AF-45F1-AD1E-16398B3127BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FCD0B4F0-32DD-44B9-8899-556F5DAE8AA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FCD0B4F0-32DD-44B9-8899-556F5DAE8AA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FCD0B4F0-32DD-44B9-8899-556F5DAE8AA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FCD0B4F0-32DD-44B9-8899-556F5DAE8AA6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CA2254AE-87E5-4402-816A-E3DE1F024693}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CA2254AE-87E5-4402-816A-E3DE1F024693}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CA2254AE-87E5-4402-816A-E3DE1F024693}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CA2254AE-87E5-4402-816A-E3DE1F024693}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FF02D406-2CA7-4D5A-979A-3694E2882C8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF02D406-2CA7-4D5A-979A-3694E2882C8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FF02D406-2CA7-4D5A-979A-3694E2882C8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FF02D406-2CA7-4D5A-979A-3694E2882C8C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {76E7371D-C80A-4102-9FF2-21F7EA09705E}
+ EndGlobalSection
+EndGlobal
diff --git a/source/EntityFrameworkCore/DotNetCore.EntityFrameworkCore.csproj b/source/EntityFrameworkCore/DotNetCore.EntityFrameworkCore.csproj
new file mode 100644
index 00000000..1228a105
--- /dev/null
+++ b/source/EntityFrameworkCore/DotNetCore.EntityFrameworkCore.csproj
@@ -0,0 +1,19 @@
+
+
+ DotNetCore.EntityFrameworkCore
+ DotNetCore.EntityFrameworkCore
+ DotNetCore.EntityFrameworkCore
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/EntityFrameworkCore
+ ORM, ObjectRelationalMapping, EntityFramework, EntityFrameworkCore, Context, Repository, GenericRepository, BaseRepository, RepositoryBase, CommandRepository, QueryRepository, CQRS, Command, Query
+ DotNetCore.EntityFrameworkCore
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/EntityFrameworkCore/Extensions.cs b/source/EntityFrameworkCore/Extensions.cs
new file mode 100644
index 00000000..ee60fb43
--- /dev/null
+++ b/source/EntityFrameworkCore/Extensions.cs
@@ -0,0 +1,40 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace DotNetCore.EntityFrameworkCore;
+
+public static class Extensions
+{
+ public static void AddContext(this IServiceCollection services, Action options) where T : DbContext
+ {
+ services.AddDbContextPool(options);
+
+ services.BuildServiceProvider().GetRequiredService().Database.Migrate();
+
+ services.AddScoped>();
+ }
+
+ public static void AddContextMemory(this IServiceCollection services) where T : DbContext
+ {
+ services.AddDbContextPool(options => options.UseInMemoryDatabase(typeof(T).Name));
+
+ services.BuildServiceProvider().GetRequiredService().Database.EnsureCreated();
+
+ services.AddScoped>();
+ }
+
+ public static DbSet CommandSet(this DbContext context) where T : class => context.DetectChangesLazyLoading(true).Set();
+
+ public static DbContext DetectChangesLazyLoading(this DbContext context, bool enabled)
+ {
+ context.ChangeTracker.AutoDetectChangesEnabled = enabled;
+ context.ChangeTracker.LazyLoadingEnabled = enabled;
+ context.ChangeTracker.QueryTrackingBehavior = enabled ? QueryTrackingBehavior.TrackAll : QueryTrackingBehavior.NoTracking;
+
+ return context;
+ }
+
+ public static IQueryable QuerySet(this DbContext context) where T : class => context.DetectChangesLazyLoading(false).Set().AsNoTracking();
+
+ public static object[] PrimaryKeyValues(this DbContext context, object entity) => context.Model.FindEntityType(typeof(T))?.FindPrimaryKey()?.Properties.Select(property => entity.GetType().GetProperty(property.Name)?.GetValue(entity, default)).ToArray();
+}
diff --git a/source/EntityFrameworkCore/Repository/EFCommandRepository.cs b/source/EntityFrameworkCore/Repository/EFCommandRepository.cs
new file mode 100644
index 00000000..beebbc3b
--- /dev/null
+++ b/source/EntityFrameworkCore/Repository/EFCommandRepository.cs
@@ -0,0 +1,87 @@
+using DotNetCore.Repositories;
+using Microsoft.EntityFrameworkCore;
+using System.Linq.Expressions;
+
+namespace DotNetCore.EntityFrameworkCore;
+
+public class EFCommandRepository(DbContext context) : ICommandRepository where T : class
+{
+ private DbSet Set => context.CommandSet();
+
+ public void Add(T item) => Set.Add(item);
+
+ public Task AddAsync(T item) => Set.AddAsync(item).AsTask();
+
+ public void AddRange(IEnumerable items) => Set.AddRange(items);
+
+ public Task AddRangeAsync(IEnumerable items) => Set.AddRangeAsync(items);
+
+ public void Delete(object key)
+ {
+ var item = Set.Find(key);
+
+ if (item is null) return;
+
+ Set.Remove(item);
+ }
+
+ public void Delete(Expression> where)
+ {
+ var items = Set.Where(where);
+
+ if (!items.Any()) return;
+
+ Set.RemoveRange(items);
+ }
+
+ public Task DeleteAsync(object key) => Task.Run(() => Delete(key));
+
+ public Task DeleteAsync(Expression> where) => Task.Run(() => Delete(where));
+
+ public void Update(T item)
+ {
+ var primaryKeyValues = context.PrimaryKeyValues(item);
+
+ var entity = Set.Find(primaryKeyValues);
+
+ if (entity is null) return;
+
+ context.Entry(entity).State = EntityState.Detached;
+
+ context.Update(item);
+ }
+
+ public Task UpdateAsync(T item) => Task.Run(() => Update(item));
+
+ public void UpdatePartial(object item)
+ {
+ var primaryKeyValues = context.PrimaryKeyValues(item);
+
+ var entity = Set.Find(primaryKeyValues);
+
+ if (entity is null) return;
+
+ var entry = context.Entry(entity);
+
+ entry.CurrentValues.SetValues(item);
+
+ foreach (var navigation in entry.Metadata.GetNavigations())
+ {
+ if (navigation.IsOnDependent || navigation.IsCollection || !navigation.ForeignKey.IsOwnership) continue;
+
+ var property = item.GetType().GetProperty(navigation.Name);
+
+ if (property is null) continue;
+
+ var value = property.GetValue(item, default);
+
+ entry.Reference(navigation.Name).TargetEntry?.CurrentValues.SetValues(value!);
+ }
+ }
+
+ public Task UpdatePartialAsync(object item) => Task.Run(() => UpdatePartial(item));
+
+ public void UpdateRange(IEnumerable items) => Set.UpdateRange(items);
+
+ public Task UpdateRangeAsync(IEnumerable items) => Task.Run(() => UpdateRange(items));
+}
diff --git a/source/EntityFrameworkCore/Repository/EFQueryRepository.cs b/source/EntityFrameworkCore/Repository/EFQueryRepository.cs
new file mode 100644
index 00000000..76eaedba
--- /dev/null
+++ b/source/EntityFrameworkCore/Repository/EFQueryRepository.cs
@@ -0,0 +1,34 @@
+using DotNetCore.Repositories;
+using Microsoft.EntityFrameworkCore;
+using System.Linq.Expressions;
+
+namespace DotNetCore.EntityFrameworkCore;
+
+public class EFQueryRepository(DbContext context) : IQueryRepository where T : class
+{
+ public IQueryable Queryable => context.QuerySet();
+
+ public bool Any() => Queryable.Any();
+
+ public bool Any(Expression> where) => Queryable.Any(where);
+
+ public Task AnyAsync() => Queryable.AnyAsync();
+
+ public Task AnyAsync(Expression> where) => Queryable.AnyAsync(where);
+
+ public long Count() => Queryable.LongCount();
+
+ public long Count(Expression> where) => Queryable.LongCount(where);
+
+ public Task CountAsync() => Queryable.LongCountAsync();
+
+ public Task CountAsync(Expression> where) => Queryable.LongCountAsync(where);
+
+ public T Get(object key) => context.DetectChangesLazyLoading(false).Set().Find(key);
+
+ public Task GetAsync(object key) => context.DetectChangesLazyLoading(false).Set().FindAsync(key).AsTask();
+
+ public IEnumerable List() => Queryable.ToList();
+
+ public async Task> ListAsync() => await Queryable.ToListAsync().ConfigureAwait(false);
+}
diff --git a/source/EntityFrameworkCore/Repository/EFRepository.cs b/source/EntityFrameworkCore/Repository/EFRepository.cs
new file mode 100644
index 00000000..4ceb169b
--- /dev/null
+++ b/source/EntityFrameworkCore/Repository/EFRepository.cs
@@ -0,0 +1,6 @@
+using DotNetCore.Repositories;
+using Microsoft.EntityFrameworkCore;
+
+namespace DotNetCore.EntityFrameworkCore;
+
+public class EFRepository(DbContext context) : Repository(new EFCommandRepository(context), new EFQueryRepository(context)) where T : class;
diff --git a/source/EntityFrameworkCore/UnitOfWork/IUnitOfWork.cs b/source/EntityFrameworkCore/UnitOfWork/IUnitOfWork.cs
new file mode 100644
index 00000000..184e4b95
--- /dev/null
+++ b/source/EntityFrameworkCore/UnitOfWork/IUnitOfWork.cs
@@ -0,0 +1,6 @@
+namespace DotNetCore.EntityFrameworkCore;
+
+public interface IUnitOfWork
+{
+ Task SaveChangesAsync();
+}
diff --git a/source/EntityFrameworkCore/UnitOfWork/UnitOfWork.cs b/source/EntityFrameworkCore/UnitOfWork/UnitOfWork.cs
new file mode 100644
index 00000000..74838286
--- /dev/null
+++ b/source/EntityFrameworkCore/UnitOfWork/UnitOfWork.cs
@@ -0,0 +1,8 @@
+using Microsoft.EntityFrameworkCore;
+
+namespace DotNetCore.EntityFrameworkCore;
+
+public sealed class UnitOfWork(TDbContext context) : IUnitOfWork where TDbContext : DbContext
+{
+ public Task SaveChangesAsync() => context.SaveChangesAsync();
+}
diff --git a/source/EntityFrameworkCore/readme.md b/source/EntityFrameworkCore/readme.md
new file mode 100644
index 00000000..43a3647c
--- /dev/null
+++ b/source/EntityFrameworkCore/readme.md
@@ -0,0 +1,119 @@
+# DotNetCore.EntityFrameworkCore
+
+## Extensions
+
+```cs
+public static class Extensions
+{
+ public static void AddContext(this IServiceCollection services, Action options) where T : DbContext { }
+
+ public static void AddContextMemory(this IServiceCollection services) where T : DbContext { }
+
+ public static DbSet CommandSet(this DbContext context) where T : class { }
+
+ public static DbContext DetectChangesLazyLoading(this DbContext context, bool enabled) { }
+
+ public static IQueryable QuerySet(this DbContext context) where T : class { }
+}
+```
+
+### EFCommandRepository
+
+```cs
+public class EFCommandRepository : ICommandRepository where T : class
+{
+ public EFCommandRepository(DbContext context) { }
+
+ public void Add(T item) { }
+
+ public Task AddAsync(T item) { }
+
+ public void AddRange(IEnumerable items) { }
+
+ public Task AddRangeAsync(IEnumerable items) { }
+
+ public void Delete(object key) { }
+
+ public void Delete(Expression> where) { }
+
+ public Task DeleteAsync(object key) { }
+
+ public Task DeleteAsync(Expression> where) { }
+
+ public void Update(T item) { }
+
+ public Task UpdateAsync(T item) { }
+
+ public void UpdatePartial(object item) { }
+
+ public Task UpdatePartialAsync(object item) { }
+
+ public void UpdateRange(IEnumerable items) { }
+
+ public Task UpdateRangeAsync(IEnumerable items) { }
+}
+```
+
+### EFQueryRepository
+
+```cs
+public class EFQueryRepository : IQueryRepository where T : class
+{
+ public EFQueryRepository(DbContext context) { }
+
+ public IQueryable Queryable { get; };
+
+ public bool Any() { }
+
+ public bool Any(Expression> where) { }
+
+ public Task AnyAsync() { }
+
+ public Task AnyAsync(Expression> where) { }
+
+ public long Count() { }
+
+ public long Count(Expression> where) { }
+
+ public Task CountAsync() { }
+
+ public Task CountAsync(Expression> where) { }
+
+ public T Get(object key) { }
+
+ public Task GetAsync(object key) { }
+
+ public IEnumerable List() { }
+
+ public async Task> ListAsync() { }
+}
+```
+
+### EFRepository
+
+```cs
+public class EFRepository : Repository where T : class
+{
+ public EFRepository(DbContext context) : base(new EFCommandRepository(context), new EFQueryRepository(context)) { }
+}
+```
+
+### IUnitOfWork
+
+```cs
+public interface IUnitOfWork
+{
+ Task SaveChangesAsync();
+}
+```
+
+### UnitOfWork
+
+```cs
+public sealed class UnitOfWork : IUnitOfWork where TDbContext : DbContext
+{
+ public UnitOfWork(TDbContext context) { }
+
+ public Task SaveChangesAsync() { }
+}
+```
diff --git a/source/Extensions/AssemblyExtensions.cs b/source/Extensions/AssemblyExtensions.cs
new file mode 100644
index 00000000..a02b2713
--- /dev/null
+++ b/source/Extensions/AssemblyExtensions.cs
@@ -0,0 +1,8 @@
+using System.Reflection;
+
+namespace DotNetCore.Extensions;
+
+public static class AssemblyExtensions
+{
+ public static FileInfo FileInfo(this Assembly assembly) => new(assembly.Location);
+}
diff --git a/source/Extensions/ByteExtensions.cs b/source/Extensions/ByteExtensions.cs
new file mode 100644
index 00000000..894e9bf5
--- /dev/null
+++ b/source/Extensions/ByteExtensions.cs
@@ -0,0 +1,36 @@
+using System.IO.Compression;
+using System.Text;
+using System.Text.Json;
+
+namespace DotNetCore.Extensions;
+
+public static class ByteExtensions
+{
+ public static byte[] Compress(this byte[] bytes)
+ {
+ if (bytes is null) return [];
+
+ using var output = new MemoryStream();
+
+ using var stream = new BrotliStream(output, CompressionMode.Compress);
+
+ stream.Write(bytes, 0, bytes.Length);
+
+ return output.ToArray();
+ }
+
+ public static byte[] Decompress(this byte[] bytes)
+ {
+ using var input = new MemoryStream(bytes);
+
+ using var stream = new BrotliStream(input, CompressionMode.Decompress);
+
+ using var output = new MemoryStream();
+
+ stream.CopyTo(output);
+
+ return output.ToArray();
+ }
+
+ public static T Object(this byte[] bytes) => JsonSerializer.Deserialize(Encoding.Default.GetString(bytes));
+}
diff --git a/source/Extensions/ClaimsPrincipalExtensions.cs b/source/Extensions/ClaimsPrincipalExtensions.cs
new file mode 100644
index 00000000..a60f392a
--- /dev/null
+++ b/source/Extensions/ClaimsPrincipalExtensions.cs
@@ -0,0 +1,20 @@
+using System.Security.Claims;
+
+namespace DotNetCore.Extensions;
+
+public static class ClaimsPrincipalExtensions
+{
+ public static Claim Claim(this ClaimsPrincipal claimsPrincipal, string claimType) => claimsPrincipal?.FindFirst(claimType);
+
+ public static IEnumerable ClaimRoles(this ClaimsPrincipal claimsPrincipal) => claimsPrincipal?.Claims("role");
+
+ public static IEnumerable Claims(this ClaimsPrincipal claimsPrincipal, string claimType) => claimsPrincipal?.FindAll(claimType).Select(x => x.Value).ToList();
+
+ public static string ClaimSub(this ClaimsPrincipal claimsPrincipal) => claimsPrincipal?.Claim("sub")?.Value;
+
+ public static long Id(this ClaimsPrincipal claimsPrincipal) => long.TryParse(claimsPrincipal.ClaimSub(), out var value) ? value : 0;
+
+ public static IEnumerable Roles(this ClaimsPrincipal claimsPrincipal) where T : Enum => claimsPrincipal.ClaimRoles().Select(value => (T)Enum.Parse(typeof(T), value)).ToList();
+
+ public static T RolesFlag(this ClaimsPrincipal claimsPrincipal) where T : Enum => (T)Enum.Parse(typeof(T), claimsPrincipal.Roles().Sum(value => Convert.ToInt64(value)).ToString(), true);
+}
diff --git a/source/Extensions/DateTimeExtensions.cs b/source/Extensions/DateTimeExtensions.cs
new file mode 100644
index 00000000..d19c7724
--- /dev/null
+++ b/source/Extensions/DateTimeExtensions.cs
@@ -0,0 +1,28 @@
+namespace DotNetCore.Extensions;
+
+public static class DateTimeExtensions
+{
+ public static List<(DateTime, DateTime)> Chunks(this DateTime startDate, DateTime endDate, int days)
+ {
+ endDate = endDate.Date.AddHours(23).AddMinutes(59).AddSeconds(59);
+
+ var chunks = new List<(DateTime, DateTime)>();
+
+ var currentDate = startDate;
+
+ while (currentDate <= endDate)
+ {
+ var chunkStartDate = currentDate;
+
+ var chunkEndDate = currentDate.AddDays(days).AddHours(23).AddMinutes(59).AddSeconds(59);
+
+ if (chunkEndDate > endDate) chunkEndDate = endDate;
+
+ chunks.Add((chunkStartDate, chunkEndDate));
+
+ currentDate = chunkEndDate.AddSeconds(1);
+ }
+
+ return chunks;
+ }
+}
diff --git a/source/Extensions/DirectoryInfoExtensions.cs b/source/Extensions/DirectoryInfoExtensions.cs
new file mode 100644
index 00000000..129d3655
--- /dev/null
+++ b/source/Extensions/DirectoryInfoExtensions.cs
@@ -0,0 +1,6 @@
+namespace DotNetCore.Extensions;
+
+public static class DirectoryInfoExtensions
+{
+ public static FileInfo GetFile(this DirectoryInfo directoryInfo, string name) => directoryInfo?.GetFiles(string.Concat(name, ".", "*")).SingleOrDefault();
+}
diff --git a/source/Extensions/DotNetCore.Extensions.csproj b/source/Extensions/DotNetCore.Extensions.csproj
new file mode 100644
index 00000000..b277aed0
--- /dev/null
+++ b/source/Extensions/DotNetCore.Extensions.csproj
@@ -0,0 +1,10 @@
+
+
+ DotNetCore.Extensions
+ DotNetCore.Extensions
+ DotNetCore.Extensions
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/Extensions
+ Extension, Extensions, Byte, Claim, ClaimsPrincipal, DirectoryInfo, Enum, Object, Queryable, String
+ DotNetCore.Extensions
+
+
diff --git a/source/Extensions/EnumExtensions.cs b/source/Extensions/EnumExtensions.cs
new file mode 100644
index 00000000..2e0bbfa6
--- /dev/null
+++ b/source/Extensions/EnumExtensions.cs
@@ -0,0 +1,28 @@
+using System.ComponentModel;
+
+namespace DotNetCore.Extensions;
+
+public static class EnumExtensions
+{
+ public static string GetDescription(this Enum value)
+ {
+ if (value is null) return default;
+
+ var attribute = value.GetAttribute();
+
+ return attribute is null ? value.ToString() : attribute.Description;
+ }
+
+ public static string[] ToArray(this Enum value) => value?.ToString().Split(", ");
+
+ private static T GetAttribute(this Enum value) where T : Attribute
+ {
+ if (value is null) return default;
+
+ var member = value.GetType().GetMember(value.ToString());
+
+ var attributes = member[0].GetCustomAttributes(typeof(T), false);
+
+ return (T)attributes[0];
+ }
+}
diff --git a/source/Extensions/ObjectExtensions.cs b/source/Extensions/ObjectExtensions.cs
new file mode 100644
index 00000000..5eeab11f
--- /dev/null
+++ b/source/Extensions/ObjectExtensions.cs
@@ -0,0 +1,31 @@
+using System.Reflection;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace DotNetCore.Extensions;
+
+public static class ObjectExtensions
+{
+ public static byte[] Bytes(this object obj) => Encoding.Default.GetBytes(JsonSerializer.Serialize(obj));
+
+ public static Dictionary Dictionary(this object obj)
+ {
+ if (obj is null) return default;
+
+ var dictionary = new Dictionary();
+
+ foreach (var property in obj.GetType().GetProperties())
+ {
+ dictionary[property.Name] = property.GetValue(obj);
+ }
+
+ return dictionary;
+ }
+
+ public static IEnumerable GetPropertiesWithAttribute(this object obj) where T : Attribute => obj.GetType().GetProperties().Where(property => Attribute.IsDefined(property, typeof(T)));
+
+ public static string Serialize(this object obj) => JsonSerializer.Serialize(obj, new JsonSerializerOptions(JsonSerializerDefaults.Web) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
+
+ public static void SetProperty(this object obj, string name, object value) => obj.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase)?.SetValue(obj, value);
+}
diff --git a/source/Extensions/QueryableExtensions.cs b/source/Extensions/QueryableExtensions.cs
new file mode 100644
index 00000000..afd9587c
--- /dev/null
+++ b/source/Extensions/QueryableExtensions.cs
@@ -0,0 +1,90 @@
+using System.Linq.Expressions;
+
+namespace DotNetCore.Extensions;
+
+public static class QueryableExtensions
+{
+ public static IQueryable Filter(this IQueryable queryable, string property, object value) => queryable.Filter(property, string.Empty, value);
+
+ public static IQueryable Filter(this IQueryable queryable, string property, string comparison, object value)
+ {
+ if (string.IsNullOrWhiteSpace(property) || value is null || string.IsNullOrWhiteSpace(value.ToString())) return queryable;
+
+ var parameter = Expression.Parameter(typeof(T));
+
+ var left = Create(property, parameter);
+
+ try
+ {
+ var propertyInfo = typeof(T).GetProperty(property);
+
+ if (propertyInfo is null) return queryable;
+
+ var type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
+
+ value = Change(value, type);
+ }
+ catch
+ {
+ return Enumerable.Empty().AsQueryable();
+ }
+
+ var right = Expression.Constant(value, left.Type);
+
+ var body = Create(left, comparison, right);
+
+ var expression = Expression.Lambda>(body, parameter);
+
+ return queryable.Where(expression);
+ }
+
+ public static IQueryable Order(this IQueryable queryable, string property, bool ascending)
+ {
+ if (queryable is null || string.IsNullOrWhiteSpace(property)) return queryable;
+
+ var parameter = Expression.Parameter(typeof(T));
+
+ var body = Create(property, parameter);
+
+ dynamic expression = Expression.Lambda(body, parameter);
+
+ return ascending ? Queryable.OrderBy(queryable, expression) : Queryable.OrderByDescending(queryable, expression);
+ }
+
+ public static IQueryable Page(this IQueryable queryable, int index, int size) => queryable is null || index <= 0 || size <= 0 ? queryable : queryable.Skip((index - 1) * size).Take(size);
+
+ private static object Change(object value, Type type)
+ {
+ if (type.BaseType != typeof(Enum)) return Convert.ChangeType(value, type);
+
+ var stringValue = value.ToString();
+
+ if (stringValue is null) return default;
+
+ value = Enum.Parse(type, stringValue);
+
+ return Convert.ChangeType(value, type);
+ }
+
+ private static Expression Create(string property, Expression parameter) => property.Split('.').Aggregate(parameter, Expression.Property);
+
+ private static Expression Create(Expression left, string comparison, Expression right)
+ {
+ if (string.IsNullOrWhiteSpace(comparison) && left.Type == typeof(string))
+ {
+ return Expression.Call(left, nameof(string.Contains), Type.EmptyTypes, right);
+ }
+
+ var type = comparison switch
+ {
+ "<" => ExpressionType.LessThan,
+ "<=" => ExpressionType.LessThanOrEqual,
+ ">" => ExpressionType.GreaterThan,
+ ">=" => ExpressionType.GreaterThanOrEqual,
+ "!=" => ExpressionType.NotEqual,
+ _ => ExpressionType.Equal
+ };
+
+ return Expression.MakeBinary(type, left, right);
+ }
+}
diff --git a/source/Extensions/StreamExtensions.cs b/source/Extensions/StreamExtensions.cs
new file mode 100644
index 00000000..b447b28a
--- /dev/null
+++ b/source/Extensions/StreamExtensions.cs
@@ -0,0 +1,13 @@
+namespace DotNetCore.Extensions;
+
+public static class StreamExtensions
+{
+ public static string ToBase64String(this Stream stream)
+ {
+ using var memoryStream = new MemoryStream();
+
+ stream.CopyTo(memoryStream);
+
+ return Convert.ToBase64String(memoryStream.ToArray());
+ }
+}
diff --git a/source/Extensions/StringExtensions.cs b/source/Extensions/StringExtensions.cs
new file mode 100644
index 00000000..adf03906
--- /dev/null
+++ b/source/Extensions/StringExtensions.cs
@@ -0,0 +1,48 @@
+using System.Net.Mail;
+using System.Numerics;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Text.RegularExpressions;
+
+namespace DotNetCore.Extensions;
+
+public static class StringExtensions
+{
+ public static T Deserialize(this string value) where T : class
+ {
+ return string.IsNullOrWhiteSpace(value)
+ ? default
+ : JsonSerializer.Deserialize(value, new JsonSerializerOptions(JsonSerializerDefaults.Web)
+ {
+ NumberHandling = JsonNumberHandling.AllowReadingFromString,
+ PropertyNameCaseInsensitive = true
+ });
+ }
+
+ public static string ExtractNumbers(this string value) => string.IsNullOrWhiteSpace(value) ? value : Regex.Replace(value, "[^0-9]", string.Empty);
+
+ public static bool IsDate(this string value) => !string.IsNullOrWhiteSpace(value) && DateOnly.TryParseExact(value, "dd/MM/yyyy", out _);
+
+ public static bool IsEmail(this string value) => !string.IsNullOrWhiteSpace(value) && MailAddress.TryCreate(value, out _);
+
+ public static bool IsInteger(this string value) => !string.IsNullOrWhiteSpace(value) && BigInteger.TryParse(value, out _);
+
+ public static bool IsLogin(this string value) => !string.IsNullOrWhiteSpace(value) && new Regex("^[a-z0-9._-]{10,50}$").IsMatch(value);
+
+ public static bool IsNumber(this string value) => !string.IsNullOrWhiteSpace(value) && decimal.TryParse(value, out _);
+
+ public static bool IsPassword(this string value) => !string.IsNullOrWhiteSpace(value) && new Regex(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d\s]).{10,50}$").IsMatch(value);
+
+ public static bool IsTime(this string value) => !string.IsNullOrWhiteSpace(value) && TimeOnly.TryParseExact(value, "HH:mm:ss", out _);
+
+ public static bool IsUrl(this string value) => !string.IsNullOrWhiteSpace(value) && Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out _);
+
+ public static string RemoveAccents(this string value) => string.IsNullOrWhiteSpace(value) ? value : Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(value));
+
+ public static string RemoveDuplicateSpaces(this string value) => string.IsNullOrWhiteSpace(value) ? value : Regex.Replace(value, @"\s+", " ");
+
+ public static string RemoveSpecialCharacters(this string value) => string.IsNullOrWhiteSpace(value) ? value : Regex.Replace(value, "[^0-9a-zA-Z ]+", string.Empty);
+
+ public static string Sanitize(this string value) => string.IsNullOrWhiteSpace(value) ? value : value.RemoveSpecialCharacters().RemoveDuplicateSpaces().RemoveAccents();
+}
diff --git a/source/Extensions/readme.md b/source/Extensions/readme.md
new file mode 100644
index 00000000..3eb23296
--- /dev/null
+++ b/source/Extensions/readme.md
@@ -0,0 +1,149 @@
+# DotNetCore.Extensions
+
+## AssemblyExtensions
+
+```cs
+public static class AssemblyExtensions
+{
+ public static FileInfo FileInfo(this Assembly assembly) { }
+}
+```
+
+## ByteExtensions
+
+```cs
+public static class ByteExtensions
+{
+ public static byte[] Compress(this byte[] bytes) { }
+
+ public static byte[] Decompress(this byte[] bytes) { }
+
+ public static T Object(this byte[] bytes) { }
+}
+```
+
+## ClaimsPrincipalExtensions
+
+```cs
+public static class ClaimsPrincipalExtensions
+{
+ public static Claim Claim(this ClaimsPrincipal claimsPrincipal, string claimType) { }
+
+ public static IEnumerable ClaimRoles(this ClaimsPrincipal claimsPrincipal) { }
+
+ public static IEnumerable Claims(this ClaimsPrincipal claimsPrincipal, string claimType) { }
+
+ public static string ClaimSub(this ClaimsPrincipal claimsPrincipal) { }
+
+ public static long Id(this ClaimsPrincipal claimsPrincipal) { }
+
+ public static IEnumerable Roles(this ClaimsPrincipal claimsPrincipal) where T : Enum { }
+
+ public static T RolesFlag(this ClaimsPrincipal claimsPrincipal) where T : Enum { }
+}
+```
+
+## DateTimeExtensions
+
+```cs
+public static class DateTimeExtensions
+{
+ public static List<(DateTime, DateTime)> Chunks(this DateTime startDate, DateTime endDate, int days) { }
+}
+```
+
+## DirectoryInfoExtensions
+
+```cs
+public static class DirectoryInfoExtensions
+{
+ public static FileInfo GetFile(this DirectoryInfo directoryInfo, string name) { }
+}
+```
+
+## EnumExtensions
+
+```cs
+public static class EnumExtensions
+{
+ public static string GetDescription(this Enum value) { }
+
+ public static string[] ToArray(this Enum value) { }
+}
+```
+
+## ObjectExtensions
+
+```cs
+public static class ObjectExtensions
+{
+ public static byte[] Bytes(this object obj) { }
+
+ public static Dictionary Dictionary(this object obj) { }
+
+ public static IEnumerable GetPropertiesWithAttribute(this object obj) where T : Attribute { }
+
+ public static string Serialize(this object obj) { }
+
+ public static void SetProperty(this object obj, string name, object value) { }
+}
+```
+
+## QueryableExtensions
+
+```cs
+public static class QueryableExtensions
+{
+ public static IQueryable Filter(this IQueryable queryable, string property, object value) { }
+
+ public static IQueryable Filter(this IQueryable queryable, string property, string comparison, object value) { }
+
+ public static IQueryable Order(this IQueryable queryable, string property, bool ascending) { }
+
+ public static IQueryable Page(this IQueryable queryable, int index, int size) { }
+}
+```
+
+## StreamExtensions
+
+```cs
+public static class StreamExtensions
+{
+ public static string ToBase64String(this Stream stream) { }
+}
+```
+
+## StringExtensions
+
+```cs
+public static class StringExtensions
+{
+ public static T Deserialize(this string value) where T : class { }
+
+ public static string ExtractNumbers(this string value) { }
+
+ public static bool IsDate(this string value) { }
+
+ public static bool IsEmail(this string value) { }
+
+ public static bool IsInteger(this string value) { }
+
+ public static bool IsLogin(this string value) { }
+
+ public static bool IsNumber(this string value) { }
+
+ public static bool IsPassword(this string value) { }
+
+ public static bool IsTime(this string value) { }
+
+ public static bool IsUrl(this string value) { }
+
+ public static string RemoveAccents(this string value) { }
+
+ public static string RemoveDuplicateSpaces(this string value) { }
+
+ public static string RemoveSpecialCharacters(this string value) { }
+
+ public static string Sanitize(this string value) { }
+}
+```
diff --git a/source/IoC/DotNetCore.IoC.csproj b/source/IoC/DotNetCore.IoC.csproj
new file mode 100644
index 00000000..2c5f49d9
--- /dev/null
+++ b/source/IoC/DotNetCore.IoC.csproj
@@ -0,0 +1,18 @@
+
+
+ DotNetCore.IoC
+ DotNetCore.IoC
+ DotNetCore.IoC
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/IoC
+ DI, DependencyInjection, IoC, InversionOfControl
+ DotNetCore.IoC
+
+
+
+
+
+
+
+
+
+
diff --git a/source/IoC/Extensions.cs b/source/IoC/Extensions.cs
new file mode 100644
index 00000000..6c97895c
--- /dev/null
+++ b/source/IoC/Extensions.cs
@@ -0,0 +1,39 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyModel;
+using Scrutor;
+using System.Reflection;
+
+namespace DotNetCore.IoC;
+
+public static class Extensions
+{
+ public static T AddAppSettings(this IServiceCollection services) where T : class
+ {
+ var appSettings = new ConfigurationBuilder().Configuration().Get();
+
+ services.AddSingleton(appSettings);
+
+ return appSettings;
+ }
+
+ public static T AddAppSettings(this IServiceCollection services, string section) where T : class
+ {
+ var appSettings = new ConfigurationBuilder().Configuration().GetSection(section).Get();
+
+ services.AddSingleton(appSettings);
+
+ return appSettings;
+ }
+
+ public static void AddClassesMatchingInterfaces(this IServiceCollection services, string @namespace)
+ {
+ var assemblies = DependencyContext.Default.GetDefaultAssemblyNames().Where(assembly => assembly.FullName.StartsWith(@namespace)).Select(Assembly.Load);
+
+ services.Scan(scan => scan.FromAssemblies(assemblies).AddClasses().UsingRegistrationStrategy(RegistrationStrategy.Skip).AsMatchingInterface().WithScopedLifetime());
+ }
+
+ public static IConfigurationRoot Configuration(this IConfigurationBuilder configuration) => configuration.AddJsonFile("AppSettings.json", false, true).AddEnvironmentVariables().Build();
+
+ public static string GetConnectionString(this IServiceCollection services, string name) => services.BuildServiceProvider().GetRequiredService().GetConnectionString(name);
+}
diff --git a/source/IoC/readme.md b/source/IoC/readme.md
new file mode 100644
index 00000000..f4ba0dc6
--- /dev/null
+++ b/source/IoC/readme.md
@@ -0,0 +1,18 @@
+# DotNetCore.IoC
+
+## Extensions
+
+```cs
+public static class Extensions
+{
+ public static T AddAppSettings(this IServiceCollection services) where T : class { }
+
+ public static T AddAppSettings(this IServiceCollection services, string section) where T : class { }
+
+ public static void AddClassesMatchingInterfaces(this IServiceCollection services, string @namespace) { }
+
+ public static IConfigurationRoot Configuration(this IConfigurationBuilder configuration) { }
+
+ public static string GetConnectionString(this IServiceCollection services, string name) { }
+}
+```
diff --git a/source/Logging/DotNetCore.Logging.csproj b/source/Logging/DotNetCore.Logging.csproj
new file mode 100644
index 00000000..9c93494a
--- /dev/null
+++ b/source/Logging/DotNetCore.Logging.csproj
@@ -0,0 +1,21 @@
+
+
+ DotNetCore.Logging
+ DotNetCore.Logging
+ DotNetCore.Logging
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/Logging
+ Log, Logging, Logger
+ DotNetCore.Logging
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/Logging/Extensions.cs b/source/Logging/Extensions.cs
new file mode 100644
index 00000000..ff3d5c8c
--- /dev/null
+++ b/source/Logging/Extensions.cs
@@ -0,0 +1,31 @@
+using DotNetCore.IoC;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Serilog;
+
+namespace DotNetCore.Logging;
+
+public static class Extensions
+{
+ public static void Log(this Microsoft.Extensions.Logging.ILogger logger, HttpResponseMessage response) => logger.Log
+ (
+ response.IsSuccessStatusCode ? LogLevel.Information : LogLevel.Error,
+ "{Url} {Method} {Request} {Response}",
+ response.RequestMessage?.RequestUri,
+ response.RequestMessage?.Method,
+ response.RequestMessage?.Content?.ReadAsStringAsync().Result,
+ response.Content.ReadAsStringAsync().Result
+ );
+
+ public static IHostBuilder UseSerilog(this IHostBuilder builder)
+ {
+ var configuration = new ConfigurationBuilder().Configuration();
+
+ Serilog.Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
+
+ SerilogHostBuilderExtensions.UseSerilog(builder);
+
+ return builder;
+ }
+}
diff --git a/source/Logging/readme.md b/source/Logging/readme.md
new file mode 100644
index 00000000..115fbdc8
--- /dev/null
+++ b/source/Logging/readme.md
@@ -0,0 +1,12 @@
+# DotNetCore.Logging
+
+## Extensions
+
+```cs
+public static class Extensions
+{
+ public static void Log(this ILogger logger, HttpResponseMessage response) { }
+
+ public static IHostBuilder UseSerilog(this IHostBuilder builder) { }
+}
+```
diff --git a/source/Mapping/DotNetCore.Mapping.csproj b/source/Mapping/DotNetCore.Mapping.csproj
new file mode 100644
index 00000000..c15f5825
--- /dev/null
+++ b/source/Mapping/DotNetCore.Mapping.csproj
@@ -0,0 +1,13 @@
+
+
+ DotNetCore.Mapping
+ DotNetCore.Mapping
+ DotNetCore.Mapping
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/Mapping
+ Map, Mapping, Mapper, Clone, Merge, ObjectMap, ObjectMapping, ObjectMapper, ObjectClone, ObjectMerge
+ DotNetCore.Mapping
+
+
+
+
+
diff --git a/source/Mapping/Extensions.cs b/source/Mapping/Extensions.cs
new file mode 100644
index 00000000..9f0a9dd3
--- /dev/null
+++ b/source/Mapping/Extensions.cs
@@ -0,0 +1,16 @@
+using AgileObjects.AgileMapper;
+
+namespace DotNetCore.Mapping;
+
+public static class Extensions
+{
+ public static TSource Clone(this TSource source) => source is null ? default : Mapper.DeepClone(source);
+
+ public static TDestination Map(this TSource source) => source is null ? default : Mapper.Map(source).ToANew();
+
+ public static TDestination Map(this object source) => source is null ? default : Mapper.Map(source).ToANew();
+
+ public static TDestination Map(this TSource source, TDestination destination) => Mapper.Map(source).OnTo(destination);
+
+ public static IQueryable Project(this IQueryable queryable) => queryable.Project().To();
+}
diff --git a/source/Mapping/readme.md b/source/Mapping/readme.md
new file mode 100644
index 00000000..8ef1cc00
--- /dev/null
+++ b/source/Mapping/readme.md
@@ -0,0 +1,18 @@
+# DotNetCore.Mapping
+
+## Extensions
+
+```cs
+public static class Extensions
+{
+ public static TSource Clone(this TSource source) { }
+
+ public static TDestination Map(this TSource source) { }
+
+ public static TDestination Map(this object source) { }
+
+ public static TDestination Map(this TSource source, TDestination destination) { }
+
+ public static IQueryable Project(this IQueryable queryable) { }
+}
+```
diff --git a/source/Mediator/DotNetCore.Mediator.csproj b/source/Mediator/DotNetCore.Mediator.csproj
new file mode 100644
index 00000000..00f0bf50
--- /dev/null
+++ b/source/Mediator/DotNetCore.Mediator.csproj
@@ -0,0 +1,18 @@
+
+
+ DotNetCore.Mediator
+ DotNetCore.Mediator
+ DotNetCore.Mediator
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/Mediator
+ Mediator, MediatorPattern, Pattern, CQRS, Command, CommandHandler, Query, QueryHandler, Handler, Request, Response
+ DotNetCore.Mediator
+
+
+
+
+
+
+
+
+
+
diff --git a/source/Mediator/Extensions.cs b/source/Mediator/Extensions.cs
new file mode 100644
index 00000000..192723f7
--- /dev/null
+++ b/source/Mediator/Extensions.cs
@@ -0,0 +1,28 @@
+using FluentValidation;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyModel;
+using System.Reflection;
+
+namespace DotNetCore.Mediator;
+
+public static class Extensions
+{
+ public static void AddMediator(this IServiceCollection services, string @namespace)
+ {
+ services.AddScoped();
+
+ var assemblies = DependencyContext.Default!.GetDefaultAssemblyNames().Where(assembly => assembly.FullName.StartsWith(@namespace)).Select(Assembly.Load);
+
+ var types = assemblies.SelectMany(assembly => assembly.GetTypes()).ToList();
+
+ types.Where(type => type.GetInterfaces().Any(IsHandler)).ToList().ForEach(type => type.GetInterfaces().Where(IsHandler).ToList().ForEach(@interface => services.AddScoped(@interface, type)));
+
+ types.Where(type => IsType(type.BaseType, typeof(AbstractValidator<>))).ToList().ForEach(type => services.AddSingleton(type.BaseType!, type));
+
+ return;
+
+ static bool IsHandler(Type type) => IsType(type, typeof(IHandler<>)) || IsType(type, typeof(IHandler<,>));
+
+ static bool IsType(Type type, MemberInfo memberInfo) => type is not null && type.IsGenericType && type.GetGenericTypeDefinition() == memberInfo;
+ }
+}
diff --git a/source/Mediator/IHandler.cs b/source/Mediator/IHandler.cs
new file mode 100644
index 00000000..d1808587
--- /dev/null
+++ b/source/Mediator/IHandler.cs
@@ -0,0 +1,13 @@
+using DotNetCore.Results;
+
+namespace DotNetCore.Mediator;
+
+public interface IHandler
+{
+ Task HandleAsync(TRequest request);
+}
+
+public interface IHandler
+{
+ Task> HandleAsync(TRequest request);
+}
diff --git a/source/Mediator/IMediator.cs b/source/Mediator/IMediator.cs
new file mode 100644
index 00000000..80963db0
--- /dev/null
+++ b/source/Mediator/IMediator.cs
@@ -0,0 +1,10 @@
+using DotNetCore.Results;
+
+namespace DotNetCore.Mediator;
+
+public interface IMediator
+{
+ Task HandleAsync(TRequest request);
+
+ Task> HandleAsync(TRequest request);
+}
diff --git a/source/Mediator/Mediator.cs b/source/Mediator/Mediator.cs
new file mode 100644
index 00000000..d6cdc9b4
--- /dev/null
+++ b/source/Mediator/Mediator.cs
@@ -0,0 +1,42 @@
+using DotNetCore.Results;
+using FluentValidation;
+using Microsoft.Extensions.DependencyInjection;
+using System.Net;
+
+namespace DotNetCore.Mediator;
+
+public sealed class Mediator(IServiceProvider serviceProvider) : IMediator
+{
+ public async Task HandleAsync(TRequest request)
+ {
+ var (valid, message) = Validate(request);
+
+ if (!valid) return new Result(HttpStatusCode.BadRequest, message);
+
+ var handler = serviceProvider.GetRequiredService>();
+
+ return await handler.HandleAsync(request).ConfigureAwait(false);
+ }
+
+ public async Task> HandleAsync(TRequest request)
+ {
+ var (valid, message) = Validate(request);
+
+ if (!valid) return new Result(HttpStatusCode.BadRequest, message);
+
+ var handler = serviceProvider.GetRequiredService>();
+
+ return await handler.HandleAsync(request).ConfigureAwait(false);
+ }
+
+ private Tuple Validate(TRequest request)
+ {
+ var validator = serviceProvider.GetService>();
+
+ if (validator is null) return new Tuple(true, default);
+
+ var validation = validator.Validate(request);
+
+ return new Tuple(validation.IsValid, validation.ToString());
+ }
+}
diff --git a/source/Mediator/readme.md b/source/Mediator/readme.md
new file mode 100644
index 00000000..8b84afb8
--- /dev/null
+++ b/source/Mediator/readme.md
@@ -0,0 +1,63 @@
+# DotNetCore.Mediator
+
+The smallest, simplest and fastest implementation of the mediator pattern.
+
+## ASP.NET Core Startup Example
+
+```cs
+public sealed class Startup
+{
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddMediator("Namespace");
+ }
+}
+```
+
+## ASP.NET Core Controller Example
+
+```cs
+public sealed class Controller : ControllerBase
+{
+ private readonly IMediator _mediator;
+
+ public Controller(IMediator mediator)
+ {
+ _mediator = mediator;
+ }
+}
+```
+
+## Mediator
+
+```cs
+public interface IMediator
+{
+ Task HandleAsync(TRequest request);
+
+ Task> HandleAsync(TRequest request);
+}
+```
+
+```cs
+public sealed class Mediator : IMediator
+{
+ public async Task HandleAsync(TRequest request) { }
+
+ public async Task> HandleAsync(TRequest request) { }
+}
+```
+
+```cs
+public interface IHandler
+{
+ Task HandleAsync(TRequest request);
+}
+```
+
+```cs
+public interface IHandler
+{
+ Task> HandleAsync(TRequest request);
+}
+```
diff --git a/source/MongoDB/Context/IMongoContext.cs b/source/MongoDB/Context/IMongoContext.cs
new file mode 100644
index 00000000..847d12df
--- /dev/null
+++ b/source/MongoDB/Context/IMongoContext.cs
@@ -0,0 +1,8 @@
+using MongoDB.Driver;
+
+namespace DotNetCore.MongoDB;
+
+public interface IMongoContext
+{
+ IMongoDatabase Database { get; }
+}
diff --git a/source/MongoDB/Context/MongoContext.cs b/source/MongoDB/Context/MongoContext.cs
new file mode 100644
index 00000000..65925b59
--- /dev/null
+++ b/source/MongoDB/Context/MongoContext.cs
@@ -0,0 +1,8 @@
+using MongoDB.Driver;
+
+namespace DotNetCore.MongoDB;
+
+public abstract class MongoContext(string connectionString) : IMongoContext
+{
+ public IMongoDatabase Database { get; } = new MongoClient(connectionString).GetDatabase(new MongoUrl(connectionString).DatabaseName);
+}
diff --git a/source/MongoDB/Document/Document.cs b/source/MongoDB/Document/Document.cs
new file mode 100644
index 00000000..66323f2a
--- /dev/null
+++ b/source/MongoDB/Document/Document.cs
@@ -0,0 +1,12 @@
+using MongoDB.Bson;
+using MongoDB.Bson.Serialization.Attributes;
+
+namespace DotNetCore.MongoDB;
+
+public abstract class Document : IDocument
+{
+ [BsonExtraElements]
+ public BsonDocument ExtraElements { get; set; }
+
+ public ObjectId Id { get; set; }
+}
diff --git a/source/MongoDB/Document/IDocument.cs b/source/MongoDB/Document/IDocument.cs
new file mode 100644
index 00000000..9393844e
--- /dev/null
+++ b/source/MongoDB/Document/IDocument.cs
@@ -0,0 +1,8 @@
+using MongoDB.Bson;
+
+namespace DotNetCore.MongoDB;
+
+public interface IDocument
+{
+ ObjectId Id { get; set; }
+}
diff --git a/source/MongoDB/DotNetCore.MongoDB.csproj b/source/MongoDB/DotNetCore.MongoDB.csproj
new file mode 100644
index 00000000..ce4791ed
--- /dev/null
+++ b/source/MongoDB/DotNetCore.MongoDB.csproj
@@ -0,0 +1,16 @@
+
+
+ DotNetCore.MongoDB
+ DotNetCore.MongoDB
+ DotNetCore.MongoDB
+ https://github.com/rafaelfgx/DotNetCore/tree/main/source/MongoDB
+ ORM, ObjectRelationalMapping, Mongo MongoDB, Context, Repository, GenericRepository, BaseRepository, RepositoryBase, CommandRepository, QueryRepository, CQRS, Command, Query
+ DotNetCore.MongoDB
+
+
+
+
+
+
+
+
diff --git a/source/MongoDB/Filters.cs b/source/MongoDB/Filters.cs
new file mode 100644
index 00000000..9a492dcc
--- /dev/null
+++ b/source/MongoDB/Filters.cs
@@ -0,0 +1,8 @@
+using MongoDB.Driver;
+
+namespace DotNetCore.MongoDB;
+
+public static class Filters
+{
+ public static FilterDefinition Id(object value) => Builders.Filter.Eq(nameof(Id), value);
+}
diff --git a/source/MongoDB/Repository/MongoCommandRepository.cs b/source/MongoDB/Repository/MongoCommandRepository.cs
new file mode 100644
index 00000000..e2b50ba3
--- /dev/null
+++ b/source/MongoDB/Repository/MongoCommandRepository.cs
@@ -0,0 +1,42 @@
+using DotNetCore.Repositories;
+using MongoDB.Driver;
+using System.Linq.Expressions;
+
+namespace DotNetCore.MongoDB;
+
+public class MongoCommandRepository(IMongoContext context) : ICommandRepository where T : class
+{
+ private readonly IMongoCollection _collection = context.Database.GetCollection(typeof(T).Name);
+
+ public void Add(T item) => _collection.InsertOne(item);
+
+ public Task AddAsync(T item) => _collection.InsertOneAsync(item);
+
+ public void AddRange(IEnumerable items) => _collection.InsertMany(items);
+
+ public Task AddRangeAsync(IEnumerable items) => _collection.InsertManyAsync(items);
+
+ public void Delete(object key) => _collection.DeleteOne(Filters.Id(key));
+
+ public void Delete(Expression> where) => _collection.DeleteMany(where);
+
+ public Task DeleteAsync(object key) => _collection.DeleteOneAsync(Filters.Id(key));
+
+ public Task DeleteAsync(Expression> where) => _collection.DeleteManyAsync(where);
+
+ public void Update(T item) => _collection.ReplaceOne(Filters.Id(GetKey(item)), item);
+
+ public Task UpdateAsync(T item) => _collection.ReplaceOneAsync(Filters.Id(GetKey(item)), item);
+
+ public void UpdatePartial(object item) => _collection.ReplaceOne(Filters.Id(GetKey(item)), item as T);
+
+ public Task UpdatePartialAsync(object item) => _collection.ReplaceOneAsync(Filters.Id(GetKey(item)), item as T);
+
+ public void UpdateRange(IEnumerable items) => _collection.BulkWrite(WriteModels(items));
+
+ public Task UpdateRangeAsync(IEnumerable items) => _collection.BulkWriteAsync(WriteModels(items));
+
+ private static IEnumerable> WriteModels(IEnumerable items) => items.Select(item => new ReplaceOneModel(Filters.Id(GetKey(item)), item) { IsUpsert = true });
+
+ private static object GetKey(object item) => item.GetType().GetProperty("Id")?.GetValue(item, default);
+}
diff --git a/source/MongoDB/Repository/MongoQueryRepository.cs b/source/MongoDB/Repository/MongoQueryRepository.cs
new file mode 100644
index 00000000..5817e6fd
--- /dev/null
+++ b/source/MongoDB/Repository/MongoQueryRepository.cs
@@ -0,0 +1,37 @@
+using DotNetCore.Repositories;
+using MongoDB.Driver;
+using MongoDB.Driver.Linq;
+using System.Linq.Expressions;
+
+namespace DotNetCore.MongoDB;
+
+public class MongoQueryRepository(IMongoContext context) : IQueryRepository where T : class
+{
+ private readonly IMongoCollection _collection = context.Database.GetCollection(typeof(T).Name);
+
+ public IQueryable Queryable => _collection.AsQueryable();
+
+ public bool Any() => Queryable.Any();
+
+ public bool Any(Expression> where) => Queryable.Where(where).Any();
+
+ public Task AnyAsync() => Queryable.AnyAsync();
+
+ public Task AnyAsync(Expression