-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create tag and config mapster, mediatR
- Loading branch information
Showing
36 changed files
with
477 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using MediatR; | ||
|
||
namespace BuildingBlocks.Application; | ||
|
||
public interface ICommand : IRequest<Result>; | ||
public interface ICommand<TResponse> : IRequest<Result<TResponse>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using MediatR; | ||
|
||
namespace BuildingBlocks.Application; | ||
|
||
public interface ICommandHandler<in TCommand> | ||
: IRequestHandler<TCommand, Result> | ||
where TCommand : ICommand; | ||
|
||
public interface ICommandHandler<in TCommand, TResponse> | ||
: IRequestHandler<TCommand, Result<TResponse>> | ||
where TCommand : ICommand<TResponse>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
using MediatR; | ||
|
||
namespace BuildingBlocks.Application; | ||
public interface IQuery<TResponse> : IRequest<Result<TResponse>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using MediatR; | ||
|
||
namespace BuildingBlocks.Application; | ||
public interface IQueryHandler<TQuery, TResponse> | ||
: IRequestHandler<TQuery, Result<TResponse>> | ||
where TQuery : IQuery<TResponse>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.EntityFrameworkCore.Infrastructure; | ||
using Microsoft.EntityFrameworkCore.Storage; | ||
|
||
namespace BuildingBlocks.Application; | ||
public interface IUnitOfWork | ||
{ | ||
DatabaseFacade Database { get; } | ||
|
||
IDbContextTransaction GetCurrentTransaction(); | ||
|
||
Task CommitTransactionAsync(IDbContextTransaction transaction); | ||
|
||
Task<IDbContextTransaction> BeginTransactionAsync(); | ||
|
||
Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,8 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<ItemGroup> | ||
<PackageReference Include="Ardalis.Result" /> | ||
<PackageReference Include="MediatR" /> | ||
<PackageReference Include="Microsoft.EntityFrameworkCore" /> | ||
<PackageReference Include="System.Net.Http" /> | ||
<PackageReference Include="System.Text.RegularExpressions" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Folder Include="Extentions\" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
namespace BuildingBlocks; | ||
|
||
public enum ErrorType | ||
{ | ||
Failure = 0, | ||
NotFound = 1, | ||
Validation = 2, | ||
Conflict = 3, | ||
AccessUnAuthorized = 4, | ||
AccessForbidden = 5 | ||
} | ||
|
||
public class Error | ||
{ | ||
private Error( | ||
string code, | ||
string description, | ||
ErrorType errorType | ||
) | ||
{ | ||
Code = code; | ||
Description = description; | ||
ErrorType = errorType; | ||
} | ||
|
||
public string Code { get; } | ||
|
||
public string Description { get; } | ||
|
||
public ErrorType ErrorType { get; } | ||
|
||
public static Error Failure(string code, string description) => | ||
new(code, description, ErrorType.Failure); | ||
|
||
public static Error NotFound(string code, string description) => | ||
new(code, description, ErrorType.NotFound); | ||
|
||
public static Error Validation(string code, string description) => | ||
new(code, description, ErrorType.Validation); | ||
|
||
public static Error Conflict(string code, string description) => | ||
new(code, description, ErrorType.Conflict); | ||
|
||
public static Error AccessUnAuthorized(string code, string description) => | ||
new(code, description, ErrorType.AccessUnAuthorized); | ||
|
||
public static Error AccessForbidden(string code, string description) => | ||
new(code, description, ErrorType.AccessForbidden); | ||
} |
25 changes: 25 additions & 0 deletions
25
src/Core/BuildingBlocks/Extentions/GenericTypeExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace BuildingBlocks.Extentions; | ||
public static class GenericTypeExtensions | ||
{ | ||
public static string GetGenericTypeName(this Type type) | ||
{ | ||
string typeName; | ||
|
||
if (type.IsGenericType) | ||
{ | ||
var genericTypes = string.Join(",", type.GetGenericArguments().Select(t => t.Name).ToArray()); | ||
typeName = $"{type.Name.Remove(type.Name.IndexOf('`'))}<{genericTypes}>"; | ||
} | ||
else | ||
{ | ||
typeName = type.Name; | ||
} | ||
|
||
return typeName; | ||
} | ||
|
||
public static string GetGenericTypeName(this object @object) | ||
{ | ||
return @object.GetType().GetGenericTypeName(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System.Text.Json.Serialization; | ||
|
||
namespace BuildingBlocks; | ||
public class Result | ||
{ | ||
protected Result() | ||
{ | ||
IsSuccess = true; | ||
Error = default; | ||
} | ||
|
||
protected Result(Error error) | ||
{ | ||
IsSuccess = false; | ||
Error = error; | ||
} | ||
|
||
public bool IsSuccess { get; } | ||
|
||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | ||
public Error? Error { get; } | ||
|
||
public static implicit operator Result(Error error) => | ||
new(error); | ||
|
||
public static Result Success() => | ||
new(); | ||
|
||
public static Result Failure(Error error) => | ||
new(error); | ||
} | ||
|
||
public sealed class Result<TValue> : Result | ||
{ | ||
private readonly TValue? _value; | ||
|
||
private Result( | ||
TValue value | ||
) : base() | ||
{ | ||
_value = value; | ||
} | ||
|
||
private Result( | ||
Error error | ||
) : base(error) | ||
{ | ||
_value = default; | ||
} | ||
|
||
public TValue Value => | ||
IsSuccess ? _value! : throw new InvalidOperationException("Value can not be accessed when IsSuccess is false"); | ||
|
||
public static implicit operator Result<TValue>(Error error) => | ||
new(error); | ||
|
||
public static implicit operator Result<TValue>(TValue value) => | ||
new(value); | ||
|
||
public static Result<TValue> Success(TValue value) => | ||
new(value); | ||
|
||
public static new Result<TValue> Failure(Error error) => | ||
new(error); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using EnglishNote.Application.Behaviors; | ||
using FluentValidation; | ||
using Mapster; | ||
using MapsterMapper; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using System.Reflection; | ||
|
||
namespace EnglishNote.Application; | ||
|
||
public static class AddServiceExtensions | ||
{ | ||
private readonly static Assembly[] Assemblies = AppDomain.CurrentDomain.GetAssemblies(); | ||
|
||
public static IServiceCollection AddApplicationLayer(this IServiceCollection services) | ||
{ | ||
services | ||
.ConfigureMediatR() | ||
.ConfigureMapster() | ||
.ConfigureFluentValidation(); | ||
|
||
return services; | ||
} | ||
|
||
public static IServiceCollection ConfigureMediatR(this IServiceCollection services) | ||
{ | ||
services.AddMediatR(cfg => | ||
{ | ||
cfg.RegisterServicesFromAssembly(typeof(IAssemblyMarker).Assembly); | ||
|
||
cfg.AddOpenBehavior(typeof(TransactionBehavior<,>)); | ||
}); | ||
|
||
return services; | ||
} | ||
|
||
public static IServiceCollection ConfigureMapster(this IServiceCollection services) { | ||
var globalConfig = TypeAdapterConfig.GlobalSettings; | ||
globalConfig.Scan(Assemblies); | ||
|
||
services.AddSingleton(globalConfig); | ||
services.AddScoped<IMapper, ServiceMapper>(); | ||
|
||
return services; | ||
} | ||
|
||
public static IServiceCollection ConfigureFluentValidation(this IServiceCollection services) | ||
{ | ||
services.AddValidatorsFromAssembly(typeof(IAssemblyMarker).Assembly, includeInternalTypes: true); | ||
return services; | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
src/Core/EnglishNote.Application/Behaviors/TransactionBehavior.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using BuildingBlocks.Application; | ||
using BuildingBlocks.Extentions; | ||
using MediatR; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace EnglishNote.Application.Behaviors; | ||
public class TransactionBehavior<TRequest, TResponse>( | ||
IUnitOfWork unitOfWork, | ||
ILogger<TransactionBehavior<TRequest, TResponse>> logger) : | ||
IPipelineBehavior<TRequest, TResponse> where TRequest : class | ||
{ | ||
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken) | ||
{ | ||
var response = default(TResponse); | ||
var typeName = request.GetGenericTypeName(); | ||
|
||
try | ||
{ | ||
var currentTransaction = unitOfWork.GetCurrentTransaction(); | ||
bool hasActiveTransaction = currentTransaction is not null; | ||
|
||
if (hasActiveTransaction) | ||
return await next(); | ||
|
||
var strategy = unitOfWork.Database.CreateExecutionStrategy(); | ||
|
||
await strategy.ExecuteAsync(async () => | ||
{ | ||
Guid transactionId; | ||
|
||
await using var transaction = await unitOfWork.BeginTransactionAsync(); | ||
using (logger.BeginScope(new List<KeyValuePair<string, object>> { new("TransactionContext", transaction.TransactionId) })) | ||
{ | ||
logger.LogInformation("Begin transaction {TransactionId} for {CommandName} ({@Command})", transaction.TransactionId, typeName, request); | ||
|
||
response = await next(); | ||
|
||
logger.LogInformation("Commit transaction {TransactionId} for {CommandName}", transaction.TransactionId, typeName); | ||
|
||
await unitOfWork.CommitTransactionAsync(transaction); | ||
|
||
transactionId = transaction.TransactionId; | ||
} | ||
}); | ||
|
||
return response; | ||
} | ||
catch (Exception ex) | ||
{ | ||
logger.LogError(ex, "Error Handling transaction for {CommandName} ({@Command})", typeName, request); | ||
throw; | ||
} | ||
} | ||
} |
6 changes: 3 additions & 3 deletions
6
src/Core/EnglishNote.Application/EnglishNote.Application.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<ItemGroup> | ||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" /> | ||
<PackageReference Include="Mapster" /> | ||
<PackageReference Include="Mapster.DependencyInjection" /> | ||
<PackageReference Include="System.Net.Http" /> | ||
<PackageReference Include="System.Text.RegularExpressions" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\EnglishNote.Domain\EnglishNote.Domain.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Folder Include="UseCases\" /> | ||
</ItemGroup> | ||
</Project> |
4 changes: 1 addition & 3 deletions
4
src/Core/EnglishNote.Application/Class1.cs → ...nglishNote.Application/IAssemblyMarker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
namespace EnglishNote.Application; | ||
|
||
public class Class1 | ||
internal interface IAssemblyMarker | ||
{ | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
src/Core/EnglishNote.Application/UseCases/Tags/CreateTag/CreateTagCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using BuildingBlocks; | ||
using BuildingBlocks.Application; | ||
|
||
namespace EnglishNote.Application.UseCases.Tags.CreateTag; | ||
public record CreateTagCommand( | ||
string Name, | ||
string? Description | ||
) : ICommand<Guid>; |
15 changes: 15 additions & 0 deletions
15
src/Core/EnglishNote.Application/UseCases/Tags/CreateTag/CreateTagCommandHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using BuildingBlocks; | ||
using BuildingBlocks.Application; | ||
using EnglishNote.Domain.Tags; | ||
|
||
namespace EnglishNote.Application.UseCases.Tags.CreateTag; | ||
internal class CreateTagCommandHandler(ITagRepository tagRepository) : ICommandHandler<CreateTagCommand, Guid> | ||
{ | ||
public async Task<Result<Guid>> Handle(CreateTagCommand request, CancellationToken cancellationToken) | ||
{ | ||
var tag = Tag.CreateTag(request.Name, request.Description, Guid.CreateVersion7()); | ||
tagRepository.Add(tag); | ||
|
||
return tag.Id; | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
src/Core/EnglishNote.Application/UseCases/Tags/CreateTag/CreateTagCommandValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
namespace EnglishNote.Application.UseCases.Tags.CreateTag; | ||
internal class CreateTagCommandValidator | ||
{ | ||
} |
4 changes: 4 additions & 0 deletions
4
src/Core/EnglishNote.Application/UseCases/Tags/GetOneTag/GetOneTagQuery.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
namespace EnglishNote.Application.UseCases.Tags.GetOneTag; | ||
internal class GetOneTagQuery | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.