Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Commands/ErrorCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EasyWay.Samples.Commands
{
public class ErrorCommand : Command<SampleModule>
public class ErrorCommand : Command
{

}
Expand Down
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Commands/ErrorCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace EasyWay.Samples.Commands
{
public class ErrorCommandHandler : ICommandHandler<SampleModule, ErrorCommand>
public class ErrorCommandHandler : ICommandHandler<ErrorCommand>
{
public Task<CommandResult> Handle(ErrorCommand command)
{
Expand Down
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Commands/SampleCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EasyWay.Samples.Commands
{
public class SampleCommand : Command<SampleModule>, IWithConcurrencyToken
public class SampleCommand : Command, IWithConcurrencyToken
{
public Guid Id { get; init; }

Expand Down
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Commands/SampleCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace EasyWay.Samples.Commands
{
internal sealed class SampleCommandHandler : ICommandHandler<SampleModule, SampleCommand>
internal sealed class SampleCommandHandler : ICommandHandler<SampleCommand>
{
private readonly ICancellationContext _cancellationContext;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace EasyWay.Samples.Commands.WithResult
{
public class SampleCommandWithResult : Command<SampleModule, SampleCommandResult>
public class SampleCommandWithResult : Command<SampleCommandResult>, IWithConcurrencyToken
{
public string Name { get; init; }

public short ConcurrencyToken { get; init; }
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

namespace EasyWay.Samples.Commands.WithResult
{
public sealed class SampleCommandWithResultHandler : ICommandHandler<SampleModule, SampleCommandWithResult, SampleCommandResult>
public sealed class SampleCommandWithResultHandler : ICommandHandler<SampleCommandWithResult, SampleCommandResult>
{
public Task<CommandResult<SampleCommandResult>> Handle(SampleCommandWithResult command)
{
Expand Down
22 changes: 20 additions & 2 deletions samples/EasyWay.Samples/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using EasyWay.Samples;
using EasyWay.Samples.Commands;
using EasyWay.Samples.Commands.WithResult;
using EasyWay.Samples.Queries;
using Microsoft.AspNetCore.Mvc;

Expand All @@ -14,6 +16,7 @@ await kernel

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddEasyWayWebApi();

var app = builder.Build();

Expand All @@ -25,12 +28,27 @@ await kernel

app.UseHttpsRedirection();

//app.UseEasyWay();

app.MapPost("/query", async ([FromBody] SampleQuery query, IModuleExecutor<SampleModule> executor) =>

app.MapPost("/query", async ([FromBody] SampleQuery query, IModuleExecutor<SampleModule> executor, IWebApiResultMapper mapper) =>
{
var x = await executor.Query<SampleQuery, SampleQueryResult>(query);

return mapper.Map(x);
});

app.MapPost("/command", async ([FromBody] SampleCommand command, IModuleExecutor<SampleModule> executor, IWebApiResultMapper mapper) =>
{
return await executor.Execute(query);
return await executor.Command(command);
});

app.MapPost("/commandwithresult", async ([FromBody] SampleCommandWithResult command, IModuleExecutor<SampleModule> executor, IWebApiResultMapper mapper) =>
{
var x = await executor.Command<SampleCommandWithResult, SampleCommandResult>(command);

return mapper.Map(x);
});

app.Run();

Expand Down
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Queries/SampleQuery.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EasyWay.Samples.Queries
{
public class SampleQuery : Query<SampleModule, SampleQueryResult>
public class SampleQuery : Query<SampleQueryResult>
{
public required string Name { get; init; }

Expand Down
2 changes: 1 addition & 1 deletion samples/EasyWay.Samples/Queries/SampleQueryHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace EasyWay.Samples.Queries
{
public class SampleQueryHandler : IQueryHandler<SampleModule, SampleQuery, SampleQueryResult>
public class SampleQueryHandler : IQueryHandler<SampleQuery, SampleQueryResult>
{
public Task<QueryResult<SampleQueryResult>> Handle(SampleQuery query)
{
Expand Down
6 changes: 4 additions & 2 deletions samples/EasyWay.Samples/SampleModule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EasyWay.Samples.Databases;
using EasyWay.Samples.Commands;
using EasyWay.Samples.Databases;
using Microsoft.EntityFrameworkCore;
using System.Reflection;

Expand All @@ -8,7 +9,8 @@ public sealed class SampleModule : EasyWayModule
{
protected override IEnumerable<Assembly> Assemblies => new List<Assembly>
{
typeof(SampleModule).Assembly
typeof(SampleModule).Assembly,
typeof(SampleCommand).Assembly
};

protected override void ConfigureDependencies(IServiceCollection services, IConfiguration configuration)
Expand Down
16 changes: 8 additions & 8 deletions source/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
<PackageVersion Include="FluentValidation.DependencyInjectionExtensions" Version="11.11.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.10" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyModel" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
<PackageVersion Include="Scrutor" Version="5.1.0" />
<PackageVersion Include="Scrutor" Version="6.0.1" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.2.0" />
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
<PackageVersion Include="System.Text.Json" Version="9.0.2" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion source/EasyWay.WebApi/Internals/WebApiResultMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public IResult Map<TOperationResult>(CommandResult<TOperationResult> commandResu
{
return commandResult.Error switch
{
CommandErrorEnum.None => Results.Ok(),
CommandErrorEnum.None => Results.Ok(commandResult.OperationResult),
CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors),
_ => Results.StatusCode(500),
};
Expand Down
6 changes: 2 additions & 4 deletions source/EasyWay/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
/// <summary>
/// Represents a command
/// </summary>
public abstract class Command<TModule>
where TModule : EasyWayModule;
public abstract class Command;

public abstract class Command<TModule, TCommandResult>
where TModule : EasyWayModule
public abstract class Command<TCommandResult>
where TCommandResult : OperationResult;
}
10 changes: 4 additions & 6 deletions source/EasyWay/ICommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
/// Defines a handler for a command
/// </summary>
/// <typeparam name="TCommand">The type of command being handled</typeparam>
public interface ICommandHandler<TModule, TCommand>
where TModule : EasyWayModule
where TCommand : Command<TModule>
public interface ICommandHandler<TCommand>
where TCommand : Command
{
/// <summary>
/// Handles a command
Expand All @@ -15,9 +14,8 @@ public interface ICommandHandler<TModule, TCommand>
Task<CommandResult> Handle(TCommand command);
}

public interface ICommandHandler<TModule, TCommand, TOperationResult>
where TModule : EasyWayModule
where TCommand : Command<TModule, TOperationResult>
public interface ICommandHandler<TCommand, TOperationResult>
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult
{
Task<CommandResult<TOperationResult>> Handle(TCommand command);
Expand Down
4 changes: 2 additions & 2 deletions source/EasyWay/IConcurrencyConflictValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
public interface IConcurrencyConflictValidator
{
void Validate<TAggregateRoot>(TAggregateRoot aggregateRoot, IWithConcurrencyToken command)
where TAggregateRoot : AggregateRoot;
void Validate<TCommand>(AggregateRoot aggregateRoot, TCommand command)
where TCommand : Command, IWithConcurrencyToken;
}
}
10 changes: 6 additions & 4 deletions source/EasyWay/IModuleExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
public interface IModuleExecutor<TModule>
where TModule : EasyWayModule
{
Task<CommandResult> Execute<TCommand>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TModule>;
Task<CommandResult> Command<TCommand>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command;

Task<CommandResult<TOperationResult>> Execute<TOperationResult>(Command<TModule, TOperationResult> command, CancellationToken cancellationToken = default)
Task<CommandResult<TOperationResult>> Command<TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult;

Task<QueryResult<TReadModel>> Execute<TReadModel>(Query<TModule, TReadModel> query, CancellationToken cancellationToken = default)
Task<QueryResult<TReadModel>> Query<TQuery, TReadModel>(TQuery query, CancellationToken cancellationToken = default)
where TQuery : Query<TReadModel>
where TReadModel : ReadModel;
}
}
5 changes: 2 additions & 3 deletions source/EasyWay/IQueryHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ namespace EasyWay
/// Defines a handler for a query
/// </summary>
/// <typeparam name="TQuery">The type of query being handled</typeparam>
public interface IQueryHandler<TModule, TQuery, TReadModel>
where TModule : EasyWayModule
where TQuery : Query<TModule, TReadModel>
public interface IQueryHandler<TQuery, TReadModel>
where TQuery : Query<TReadModel>
where TReadModel : ReadModel
{
/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions source/EasyWay/Internals/Commands/CommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public CommandExecutor(
}

public async Task<CommandResult> Execute<TCommand>(TCommand command, CancellationToken cancellationToken)
where TCommand : Command<TModule>
where TCommand : Command
{
_cancellationContextConstructor.Set(cancellationToken);

Expand All @@ -41,7 +41,7 @@ public async Task<CommandResult> Execute<TCommand>(TCommand command, Cancellatio
}

var commandResult = await _serviceProvider
.GetRequiredService<ICommandHandler<TModule, TCommand>>()
.GetRequiredService<ICommandHandler<TCommand>>()
.Handle(command);

await _unitOfWorkCommandHandler.Handle();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,27 @@ public CommandWithOperationResultExecutor(
_unitOfWorkCommandHandler = unitOfWorkCommandHandler;
}

public async Task<CommandResult<TOperationResult>> Execute<TOperationResult>(Command<TModule, TOperationResult> command, CancellationToken cancellationToken)
public async Task<CommandResult<TOperationResult>> Command<TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult
{
_cancellationContextConstructor.Set(cancellationToken);

var commandType = command.GetType();

var validatorType = typeof(IEasyWayValidator<>).MakeGenericType(commandType);

var validator = _serviceProvider.GetService(validatorType);
var validator = _serviceProvider.GetService<IEasyWayValidator<TCommand>>();

if (validator is not null)
{
var errors = (IDictionary<string, string[]>)validatorType
.GetMethod("Validate")
?.Invoke(validator, [command]);
var errors = validator.Validate(command);

if (errors.Any())
{
return CommandResult<TOperationResult>.Validation(errors);
}
}

var commandHandlerType = typeof(ICommandHandler<,,>).MakeGenericType(typeof(TModule), commandType, typeof(TOperationResult));

var commandHandler = _serviceProvider.GetRequiredService(commandHandlerType);
var commandHandler = _serviceProvider.GetRequiredService<ICommandHandler<TCommand,TOperationResult>>();

var commandResult = await (Task<CommandResult<TOperationResult>>)commandHandlerType.GetMethod("Handle").Invoke(commandHandler, [command]);
var commandResult = await commandHandler.Handle(command);

await _unitOfWorkCommandHandler.Handle();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
{
internal sealed class ConcurrencyConflictValidator : IConcurrencyConflictValidator
{
public void Validate<TAggregateRoot>(
TAggregateRoot aggregateRoot,
IWithConcurrencyToken command)
where TAggregateRoot : AggregateRoot
public void Validate<TCommand>(AggregateRoot aggregateRoot, TCommand command)
where TCommand : Command, IWithConcurrencyToken
{
if (aggregateRoot.ConcurrencyToken == command.ConcurrencyToken)
{
Expand Down
4 changes: 2 additions & 2 deletions source/EasyWay/Internals/Commands/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ internal static IServiceCollection AddCommands(
services.AddScoped(typeof(ICommandWithOperationResultExecutor<>).MakeGenericType(moduleType), typeof(CommandWithOperationResultExecutor<>).MakeGenericType(moduleType));

services.Scan(s => s.FromAssemblies(assemblies)
.AddClasses(c => c.AssignableTo(typeof(ICommandHandler<,>)))
.AddClasses(c => c.AssignableTo(typeof(ICommandHandler<>)))
.AsImplementedInterfaces()
.WithScopedLifetime());

services.Scan(s => s.FromAssemblies(assemblies)
.AddClasses(c => c.AssignableTo(typeof(ICommandHandler<,,>)))
.AddClasses(c => c.AssignableTo(typeof(ICommandHandler<,>)))
.AsImplementedInterfaces()
.WithScopedLifetime());

Expand Down
2 changes: 1 addition & 1 deletion source/EasyWay/Internals/Commands/ICommandExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ internal interface ICommandExecutor<TModule>
where TModule : EasyWayModule
{
Task<CommandResult> Execute<TCommand>(TCommand command, CancellationToken cancellationToken)
where TCommand : Command<TModule>;
where TCommand : Command;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
internal interface ICommandWithOperationResultExecutor<TModule>
where TModule : EasyWayModule
{
Task<CommandResult<TOperationResult>> Execute<TOperationResult>(Command<TModule, TOperationResult> command, CancellationToken cancellationToken)
Task<CommandResult<TOperationResult>> Command<TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult;
}
}
14 changes: 8 additions & 6 deletions source/EasyWay/Internals/Modules/ModuleExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public ModuleExecutor(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
}

public async Task<CommandResult> Execute<TCommand>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TModule>
public async Task<CommandResult> Command<TCommand>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command
{
CommandResult commandResult;

Expand All @@ -31,7 +31,8 @@ public async Task<CommandResult> Execute<TCommand>(TCommand command, Cancellatio
return commandResult;
}

public async Task<CommandResult<TOperationResult>> Execute<TOperationResult>(Command<TModule, TOperationResult> command, CancellationToken cancellationToken = default)
public async Task<CommandResult<TOperationResult>> Command<TCommand, TOperationResult>(TCommand command, CancellationToken cancellationToken = default)
where TCommand : Command<TOperationResult>
where TOperationResult : OperationResult
{
CommandResult<TOperationResult> commandResult;
Expand All @@ -42,13 +43,14 @@ public async Task<CommandResult<TOperationResult>> Execute<TOperationResult>(Com

commandResult = await sp
.GetRequiredService<ICommandWithOperationResultExecutor<TModule>>()
.Execute(command, cancellationToken);
.Command<TCommand, TOperationResult>(command, cancellationToken);
}

return commandResult;
}

public async Task<QueryResult<TReadModel>> Execute<TReadModel>(Query<TModule, TReadModel> query, CancellationToken cancellationToken = default)
public async Task<QueryResult<TReadModel>> Query<TQuery, TReadModel>(TQuery query, CancellationToken cancellationToken = default)
where TQuery : Query<TReadModel>
where TReadModel : ReadModel
{
QueryResult<TReadModel> result;
Expand All @@ -59,7 +61,7 @@ public async Task<QueryResult<TReadModel>> Execute<TReadModel>(Query<TModule, TR

result = await sp
.GetRequiredService<IQueryExecutor<TModule>>()
.Execute(query, cancellationToken);
.Execute<TQuery, TReadModel>(query, cancellationToken);
}

return result;
Expand Down
Loading
Loading