Skip to content

Commit da41ca8

Browse files
committed
Refactoring by evolution.
1 parent 84580c2 commit da41ca8

File tree

21 files changed

+474
-476
lines changed

21 files changed

+474
-476
lines changed

RoyalCode.EnterprisePatterns/Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
<ValVer>1.0.0-preview-0.2</ValVer>
2626
<ProbVer>1.0.0-preview-1.2</ProbVer>
2727
<HintVer>1.0.0</HintVer>
28-
<SearchVer>1.0.0-preview6.0</SearchVer>
28+
<SearchVer>1.0.0-preview7.0</SearchVer>
2929
</PropertyGroup>
3030
</Project>

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Abstractions/ICreationHandler.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using RoyalCode.OperationResults;
1+
using RoyalCode.SmartProblems;
22
using RoyalCode.WorkContext.Abstractions;
33

44
namespace RoyalCode.Commands.Abstractions;
@@ -40,7 +40,7 @@ public interface ICreationHandler<TContext, in TRequest, out TEntity>
4040
/// <param name="request">The request that contains the data to create the entity.</param>
4141
/// <param name="cancellationToken">The cancellation token.</param>
4242
/// <returns>The operation result with the context.</returns>
43-
Task<OperationResult<TContext>> CreateContextAsync(IWorkContext context, TRequest request, CancellationToken cancellationToken);
43+
Task<Result<TContext>> CreateContextAsync(IWorkContext context, TRequest request, CancellationToken cancellationToken);
4444

4545
/// <summary>
4646
/// Create a new entity from the context.
@@ -72,7 +72,7 @@ public interface ICreationHandler<TContext, in TRequest, in TRootEntity, out TEn
7272
/// <param name="rootEntity">The root entity.</param>
7373
/// <param name="cancellationToken">The cancellation token.</param>
7474
/// <returns>The operation result with the context.</returns>
75-
Task<OperationResult<TContext>> CreateContextAsync(
75+
Task<Result<TContext>> CreateContextAsync(
7676
IWorkContext context, TRequest request, TRootEntity rootEntity, CancellationToken cancellationToken);
7777

7878
/// <summary>

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Abstractions/IValidableContext.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-

2-
using RoyalCode.OperationResults;
1+
using RoyalCode.SmartProblems;
32

43
namespace RoyalCode.Commands.Abstractions;
54

@@ -20,5 +19,5 @@ public interface IValidableContext
2019
/// A operation result with the problems messages if the context is invalid,
2120
/// or a operation result with success if the context is valid.
2221
/// </returns>
23-
OperationResult Validate();
22+
Result Validate();
2423
}

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Abstractions/IValidationHandler.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using RoyalCode.OperationResults;
1+
using RoyalCode.SmartProblems;
22
using RoyalCode.WorkContext.Abstractions;
33

44
namespace RoyalCode.Commands.Abstractions;
@@ -15,5 +15,5 @@ public interface IValidationHandler<in TModel>
1515
/// <param name="context">The work context.</param>
1616
/// <param name="model">The command data.</param>
1717
/// <returns>The result of the validation.</returns>
18-
OperationResult Validate(IWorkContext context, TModel model);
18+
Result Validate(IWorkContext context, TModel model);
1919
}

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Abstractions/IValidator.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-

2-
using RoyalCode.OperationResults;
1+
using RoyalCode.SmartProblems;
32

43
namespace RoyalCode.Commands.Abstractions;
54

@@ -17,5 +16,5 @@ public interface IValidator<in TModel>
1716
/// A operation result with the problems messages if the model is invalid,
1817
/// or a operation result with success if the model is valid.
1918
/// </returns>
20-
OperationResult Validate(TModel model);
19+
Result Validate(TModel model);
2120
}

RoyalCode.EnterprisePatterns/RoyalCode.Commands.AspNetCore/CreationCommandsExtensions.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-

2-
using Microsoft.AspNetCore.Routing;
1+
using Microsoft.AspNetCore.Routing;
32
using Microsoft.AspNetCore.Builder;
43
using Microsoft.AspNetCore.Http;
54
using Microsoft.AspNetCore.Mvc;
@@ -20,8 +19,6 @@ public static class CreationApi
2019
{
2120
private static readonly Dictionary<CreatePathKey, CreatePathValue> creationPathMap = new();
2221

23-
#if NET7_0_OR_GREATER
24-
2522
/// <summary>
2623
/// <para>
2724
/// Maps a default command for creating an entity.
@@ -121,8 +118,6 @@ public static RouteHandlerBuilder MapDefaultCreate<TRootEntity, TRootId, TEntity
121118
return builder.MapPost(pattern, CreationAsync<TRootEntity, TRootId, TEntity, TModel, TContext>);
122119
}
123120

124-
#endif
125-
126121
/// <summary>
127122
/// <para>
128123
/// Maps a default command for creating an entity.

RoyalCode.EnterprisePatterns/RoyalCode.Commands.AspNetCore/RoyalCode.Commands.AspNetCore.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
<ItemGroup>
2525
<FrameworkReference Include="Microsoft.AspNetCore.App" />
26-
<PackageReference Include="RoyalCode.OperationResult.ApiResults" Version="2.0.0" />
26+
<PackageReference Include="RoyalCode.SmartProblems.ApiResults" Version="$(ProbVer)" />
2727
<ProjectReference Include="..\RoyalCode.Commands.Handlers\RoyalCode.Commands.Handlers.csproj" />
2828
</ItemGroup>
2929

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Automation/Defaults.cs

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-

2-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.DependencyInjection;
32
using RoyalCode.Extensions.AsyncExpressionsBuilders;
4-
using RoyalCode.OperationResults;
53
using RoyalCode.Repositories.Abstractions;
4+
using RoyalCode.SmartProblems;
65
using System.Diagnostics.CodeAnalysis;
76
using System.Linq.Expressions;
87
using System.Reflection;
@@ -12,7 +11,7 @@ namespace RoyalCode.Commands.Abstractions.Defaults;
1211

1312
public interface ICommandContextFactory
1413
{
15-
Task<OperationResult<TContext>> CreateCreationContextAsync<TContext, TModel>(TModel model)
14+
Task<Result<TContext>> CreateCreationContextAsync<TContext, TModel>(TModel model)
1615
where TContext : ICreationContext<TModel>
1716
where TModel : class;
1817
}
@@ -21,7 +20,7 @@ public interface ICreationContextBuilder<TContext, TModel>
2120
where TContext : ICreationContext<TModel>
2221
where TModel : class
2322
{
24-
Task<OperationResult<TContext>> BuildAsync(TModel model);
23+
Task<Result<TContext>> BuildAsync(TModel model);
2524
}
2625

2726
internal class DefaultCommandContextFactory : ICommandContextFactory
@@ -31,7 +30,7 @@ internal class DefaultCommandContextFactory : ICommandContextFactory
3130
private readonly ContextBuilderGenerator generator;
3231

3332
// TODO: Usar OperationResult
34-
public async Task<OperationResult<TContext>> CreateCreationContextAsync<TContext, TModel>(TModel model)
33+
public async Task<Result<TContext>> CreateCreationContextAsync<TContext, TModel>(TModel model)
3534
where TContext : ICreationContext<TModel>
3635
where TModel : class
3736
{
@@ -65,7 +64,7 @@ private bool TryGetContextBuilderType<TContext, TModel>([NotNullWhen(true)] out
6564
return contextBuilderType is not null;
6665
}
6766

68-
public Task<OperationResult<TContext>> CreateAsync<TContext, TRootEntity, TModel>(TRootEntity entity, TModel model)
67+
public Task<Result<TContext>> CreateAsync<TContext, TRootEntity, TModel>(TRootEntity entity, TModel model)
6968
where TContext : ICreationContext<TRootEntity, TModel>
7069
where TRootEntity : class
7170
where TModel : class
@@ -202,7 +201,7 @@ private Expression GenerateExpression(GeneratorPropertiesResolution resolution)
202201
var asyncScopeBuilder = new AsyncScopeBuilder();
203202

204203
// expression da variável result do tipo BaseResult
205-
var resultVariable = Expression.Variable(typeof(OperationResult), "result");
204+
var resultVariable = Expression.Variable(typeof(Result), "result");
206205

207206
// para cada match, deve ser gerado um bloco de código que faz a busca da entidade no repositório.
208207
foreach (var match in resolution.PropertyMatches)
@@ -335,17 +334,17 @@ internal sealed class ContextBuilderMap
335334
{
336335
private readonly Dictionary<(Type, Type), object> modelBuilders = new();
337336

338-
public Func<TModel, IServiceProvider, Task<OperationResult<TContext>>>? GetBuilder<TContext, TModel>()
337+
public Func<TModel, IServiceProvider, Task<Result<TContext>>>? GetBuilder<TContext, TModel>()
339338
where TContext : ICreationContext<TModel>
340339
where TModel : class
341340
{
342341
return modelBuilders.TryGetValue((typeof(TContext), typeof(TModel)), out var builder)
343-
? (Func<TModel, IServiceProvider, Task<OperationResult<TContext>>>)builder
342+
? (Func<TModel, IServiceProvider, Task<Result<TContext>>>)builder
344343
: null;
345344
}
346345

347346
// add builder
348-
public void AddBuilder<TContext, TModel>(Func<TModel, IServiceProvider, Task<OperationResult<TContext>>> builder)
347+
public void AddBuilder<TContext, TModel>(Func<TModel, IServiceProvider, Task<Result<TContext>>> builder)
349348
where TContext : ICreationContext<TModel>
350349
where TModel : class
351350
{
@@ -369,7 +368,7 @@ public DefaultContextBuilder(IServiceProvider serviceProvider, ContextBuilderMap
369368
this.contextBuilderMap = contextBuilderMap;
370369
}
371370

372-
public Task<OperationResult<TContext>> BuildAsync(TModel model)
371+
public Task<Result<TContext>> BuildAsync(TModel model)
373372
{
374373
var builderFunction = contextBuilderMap.GetBuilder<TContext, TModel>()
375374
?? throw new InvalidOperationException(
@@ -385,7 +384,7 @@ internal sealed class DefaultValidableContextBuilder<TContext, TModel> : ICreati
385384
{
386385

387386

388-
public Task<OperationResult<TContext>> BuildAsync(TModel model)
387+
public Task<Result<TContext>> BuildAsync(TModel model)
389388
{
390389
throw new NotImplementedException();
391390
}

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Handlers/CreateCommandHandler.cs

+50-50
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using RoyalCode.Commands.Abstractions;
22
using RoyalCode.Entities;
3-
using RoyalCode.OperationResults;
3+
using RoyalCode.SmartProblems;
44
using RoyalCode.WorkContext.Abstractions;
55

66
namespace RoyalCode.Commands.Handlers;
@@ -45,27 +45,27 @@ public CreateCommandHandler(
4545
/// <param name="model">The input model.</param>
4646
/// <param name="token">The cancellation token.</param>
4747
/// <returns>The result of the operation with the created entity.</returns>
48-
public async Task<OperationResult<TEntity>> HandleAsync(TModel model, CancellationToken token)
48+
public async Task<Result<TEntity>> HandleAsync(TModel model, CancellationToken token)
4949
{
5050
foreach (var validator in validators)
5151
{
5252
var result = validator.Validate(model);
53-
if (result.TryGetError(out var error))
54-
return error;
53+
if (result.HasProblems(out var problems))
54+
return problems;
5555
}
5656

5757
if (creationHandler is IValidationHandler<TModel> validationHandler)
5858
{
5959
var result = validationHandler.Validate(context, model);
60-
if (result.TryGetError(out var error))
61-
return error;
60+
if (result.HasProblems(out var problems))
61+
return problems;
6262
}
6363

6464
var entity = creationHandler.Create(model);
6565
context.Repository<TEntity>().Add(entity);
6666

6767
var saveResult = await context.SaveAsync(token);
68-
return saveResult.Convert(entity);
68+
return saveResult.Map(entity);
6969
}
7070
}
7171

@@ -111,38 +111,38 @@ public CreateCommandHandler(
111111
/// <param name="model">The input model.</param>
112112
/// <param name="token">The cancellation token.</param>
113113
/// <returns>The result of the operation with the created entity.</returns>
114-
public async Task<OperationResult<TEntity>> HandleAsync(TModel model, CancellationToken token)
114+
public async Task<Result<TEntity>> HandleAsync(TModel model, CancellationToken token)
115115
{
116116
foreach (var validator in validators)
117117
{
118118
var result = validator.Validate(model);
119-
if (result.TryGetError(out var error))
120-
return error;
119+
if (result.HasProblems(out var problems))
120+
return problems;
121121
}
122122

123123
if (creationHandler is IValidationHandler<TModel> validationHandler)
124124
{
125125
var result = validationHandler.Validate(context, model);
126-
if (result.TryGetError(out var error))
127-
return error;
126+
if (result.HasProblems(out var problems))
127+
return problems;
128128
}
129129

130-
var creationContextResult = await creationHandler.CreateContextAsync(context, model, token);
131-
if (creationContextResult.IsFailureOrGetValue(out var creationContext))
132-
return creationContextResult.Convert<TEntity>();
133-
134-
if (creationContext is IValidableContext validable)
135-
{
136-
var result = validable.Validate();
137-
if (result.TryGetError(out var error))
138-
return error;
139-
}
140-
141-
var entity = creationHandler.Create(creationContext);
142-
context.Repository<TEntity>().Add(entity);
143-
144-
var saveResult = await context.SaveAsync(token);
145-
return saveResult.Convert(entity);
130+
return await creationHandler.CreateContextAsync(context, model, token)
131+
.MapAsync(async creationContext =>
132+
{
133+
if (creationContext is IValidableContext validable)
134+
{
135+
var result = validable.Validate();
136+
if (result.HasProblems(out var problems))
137+
return problems;
138+
}
139+
140+
var entity = creationHandler.Create(creationContext);
141+
context.Repository<TEntity>().Add(entity);
142+
143+
var saveResult = await context.SaveAsync(token);
144+
return saveResult.Map(entity);
145+
});
146146
}
147147
}
148148

@@ -193,41 +193,41 @@ public CreateCommandHandler(
193193
/// <param name="model">The input model.</param>
194194
/// <param name="token">The cancellation token.</param>
195195
/// <returns>The result of the operation with the created entity.</returns>
196-
public async Task<OperationResult<TEntity>> HandleAsync(TRootId id, TModel model, CancellationToken token)
196+
public async Task<Result<TEntity>> HandleAsync(TRootId id, TModel model, CancellationToken token)
197197
{
198198
foreach (var validator in validators)
199199
{
200200
var result = validator.Validate(model);
201-
if (result.TryGetError(out var error))
201+
if (result.HasProblems(out var error))
202202
return error;
203203
}
204204

205205
if (creationHandler is IValidationHandler<TModel> validationHandler)
206206
{
207207
var result = validationHandler.Validate(context, model);
208-
if (result.TryGetError(out var error))
209-
return error;
208+
if (result.HasProblems(out var problems))
209+
return problems;
210210
}
211211

212212
var rootEntity = await context.Repository<TRootEntity>().FindAsync(id!);
213213
if (rootEntity is null)
214-
return ResultMessage.NotFound(CommandsErrorMessages.CreateNotFoundMessage<TRootEntity>(id), nameof(id));
215-
216-
var creationContextResult = await creationHandler.CreateContextAsync(context, model, rootEntity, token);
217-
if (creationContextResult.IsFailureOrGetValue(out var creationContext))
218-
return creationContextResult.Convert<TEntity>();
219-
220-
if (creationContext is IValidableContext validable)
221-
{
222-
var result = validable.Validate();
223-
if (result.TryGetError(out var error))
224-
return error;
225-
}
226-
227-
var entity = creationHandler.Create(creationContext);
228-
context.Repository<TEntity>().Add(entity);
229-
230-
var saveResult = await context.SaveAsync(token);
231-
return saveResult.Convert(entity);
214+
return Problems.NotFound(CommandsErrorMessages.CreateNotFoundMessage<TRootEntity>(id), nameof(id));
215+
216+
return await creationHandler.CreateContextAsync(context, model, rootEntity, token)
217+
.MapAsync(async creationContext =>
218+
{
219+
if (creationContext is IValidableContext validable)
220+
{
221+
var result = validable.Validate();
222+
if (result.HasProblems(out var problems))
223+
return problems;
224+
}
225+
226+
var entity = creationHandler.Create(creationContext);
227+
context.Repository<TEntity>().Add(entity);
228+
229+
var saveResult = await context.SaveAsync(token);
230+
return saveResult.Map(entity);
231+
});
232232
}
233233
}

RoyalCode.EnterprisePatterns/RoyalCode.Commands.Tests/CreateHandlerTests.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Microsoft.EntityFrameworkCore;
33
using Microsoft.Extensions.DependencyInjection;
44
using Microsoft.Extensions.DependencyInjection.Extensions;
5-
using RoyalCode.Commands.Abstractions;
65
using RoyalCode.Commands.Abstractions.Attributes;
76
using RoyalCode.Commands.Handlers;
87
using RoyalCode.Entities;
@@ -50,7 +49,7 @@ public async Task CreateSimple()
5049
var dto = new SimpleDto { Name = "Test" };
5150
var result = await handler.HandleAsync(dto, default);
5251
scope.Dispose();
53-
bool success = result.TryGetValue(out var entity);
52+
bool success = result.HasValue(out var entity);
5453

5554
// assert
5655
Assert.True(success);

RoyalCode.EnterprisePatterns/RoyalCode.Events.Outbox.Abstractions/Contracts/RegisterConsumer.cs

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public sealed class RegisterConsumer
1919
/// </summary>
2020
public bool ConsumeFromLastMessage { get; init; }
2121

22+
/// <summary>
23+
/// Apply validations to the data model.
24+
/// </summary>
25+
/// <param name="problems">Problems if the model is invalid.</param>
26+
/// <returns>True if there are problems, i.e. it is invalid, false if it is valid.</returns>
2227
public bool HasProblems([NotNullWhen(true)] out Problems? problems)
2328
{
2429
return Rules.Set<RegisterConsumer>()

0 commit comments

Comments
 (0)