Skip to content

Commit

Permalink
Merge pull request #328 from J-Tech-Japan/324-needs-contextappendeven…
Browse files Browse the repository at this point in the history
…ts-multiple-add
  • Loading branch information
tomohisa authored Jun 25, 2024
2 parents fc0475e + bf15d06 commit 1fdc04e
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 99 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using FeatureCheck.Domain.Aggregates.ALotOfEvents.Events;
using ResultBoxes;
using Sekiban.Core.Command;
using Sekiban.Core.Events;
namespace FeatureCheck.Domain.Aggregates.ALotOfEvents.Commands;

public record ALotOfEventsCreateCommandNext(Guid AggregateId, int NumberOfEvents)
: ICommandWithHandler<ALotOfEventsAggregate, ALotOfEventsCreateCommandNext>
{
public Guid GetAggregateId() => AggregateId;
public static ResultBox<UnitValue> HandleCommand(ALotOfEventsCreateCommandNext command, ICommandContext<ALotOfEventsAggregate> context) =>
ResultBox.FromValue(
Enumerable.Range(1, command.NumberOfEvents)
.Select(i => (IEventPayloadApplicableTo<ALotOfEventsAggregate>)new ALotOfEventsSingleEvent(i.ToString()))
.ToArray())
.Conveyor(context.AppendEvents);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using FeatureCheck.Domain.Aggregates.ALotOfEvents.Events;
using ResultBoxes;
using Sekiban.Core.Command;
namespace FeatureCheck.Domain.Aggregates.ALotOfEvents.Commands;

public record TwoEventsCreateCommand(Guid AggregateId) : ICommandWithHandler<ALotOfEventsAggregate, TwoEventsCreateCommand>
{

public Guid GetAggregateId() => AggregateId;
public static ResultBox<UnitValue> HandleCommand(TwoEventsCreateCommand command, ICommandContext<ALotOfEventsAggregate> context) =>
context.AppendEvents(new ALotOfEventsSingleEvent("0"), new ALotOfEventsSingleEvent("1"));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using FeatureCheck.Domain.Aggregates.Branches.Events;
using ResultBoxes;
using Sekiban.Core.Command;
using System.ComponentModel.DataAnnotations;
namespace FeatureCheck.Domain.Aggregates.Branches.Commands;

public record ChangeBranchNameNext(
Guid BranchId,
[property: Required]
[property: MaxLength(20)]
string Name) : ICommandWithHandlerForExistingAggregate<Branch, ChangeBranchNameNext>
{

public Guid GetAggregateId() => BranchId;
public static ResultBox<UnitValue> HandleCommand(ChangeBranchNameNext command, ICommandContext<Branch> context) =>
context.AppendEvent(new BranchNameChanged(command.Name));
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,3 @@ public record CreateBranchWithResult(
public static ResultBox<UnitValue> HandleCommand(CreateBranchWithResult command, ICommandContext<Branch> context) =>
context.AppendEvent(new BranchCreated(command.Name));
}
public record ChangeBranchNameNext(
Guid BranchId,
[property: Required]
[property: MaxLength(20)]
string Name) : ICommandWithHandlerForExistingAggregate<Branch, ChangeBranchNameNext>
{

public Guid GetAggregateId() => BranchId;
public static ResultBox<UnitValue> HandleCommand(ChangeBranchNameNext command, ICommandContext<Branch> context) =>
context.AppendEvent(new BranchNameChanged(command.Name));
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Sekiban.Aspire.Infrastructure.Cosmos</PackageId>
<Version>0.20.1</Version>
<Version>0.20.2</Version>
<Authors>J-Tech Group</Authors>
<Company>J-Tech-Japan</Company>
<PackageDescription>Sekiban - Event Sourcing Framework Cosmos Aspire Connector</PackageDescription>
<PackageVersion>0.20.1</PackageVersion>
<PackageVersion>0.20.2</PackageVersion>
<Description>Web Authorization Check become async Task</Description>
<RepositoryUrl>https://github.com/J-Tech-Japan/Sekiban</RepositoryUrl>
<RootNamespace>Sekiban.Aspire.Infrastructure.Cosmos</RootNamespace>
Expand All @@ -23,8 +23,8 @@

<ItemGroup>
<PackageReference Include="Aspire.Azure.Storage.Blobs" Version="8.0.1" />
<PackageReference Include="Sekiban.Infrastructure.Cosmos" Version="0.20.1"/>
<PackageReference Include="Sekiban.Web" Version="0.20.1"/>
<PackageReference Include="Sekiban.Infrastructure.Cosmos" Version="0.20.2"/>
<PackageReference Include="Sekiban.Web" Version="0.20.2"/>
<ProjectReference Include="..\Sekiban.Infrastructure.Cosmos\Sekiban.Infrastructure.Cosmos.csproj"/>
<ProjectReference Include="..\Sekiban.Web\Sekiban.Web.csproj"/>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
Expand Down
2 changes: 2 additions & 0 deletions src/Sekiban.Core/Command/CommandHandlerAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public ResultBox<UnitValue> AppendEvent(IEventPayloadApplicableTo<TAggregatePayl
ResultBox.Start.Conveyor(_ => _aggregate is not null ? ResultBox.FromValue(_aggregate) : new SekibanCommandHandlerAggregateNullException())
.Scan(aggregate => _events.Add(EventHelper.HandleEvent(aggregate, eventPayload, _rootPartitionKey)))
.Remap(_ => UnitValue.None);
public ResultBox<UnitValue> AppendEvents(params IEventPayloadApplicableTo<TAggregatePayload>[] eventPayloads) =>
ResultBox.FromValue(eventPayloads.ToList()).ReduceEach(UnitValue.Unit, (nextEventPayload, _) => AppendEvent(nextEventPayload));

/// <summary>
/// Common Command handler, it is used for test and production code.
Expand Down
1 change: 1 addition & 0 deletions src/Sekiban.Core/Command/ICommandContextWithoutGetState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingl
public Task<ResultBox<TOutput>> ExecuteQueryAsync<TOutput>(IQueryInput<TOutput> param) where TOutput : IQueryResponse;

public ResultBox<UnitValue> AppendEvent(IEventPayloadApplicableTo<TAggregatePayload> eventPayload);
public ResultBox<UnitValue> AppendEvents(params IEventPayloadApplicableTo<TAggregatePayload>[] eventPayloads);
}
2 changes: 2 additions & 0 deletions src/Sekiban.Core/Command/StaticCommandHandlerAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public ResultBox<UnitValue> AppendEvent(IEventPayloadApplicableTo<TAggregatePayl
ResultBox.Start.Conveyor(_ => _aggregate is not null ? ResultBox.FromValue(_aggregate) : new SekibanCommandHandlerAggregateNullException())
.Scan(aggregate => _events.Add(EventHelper.HandleEvent(aggregate, eventPayload, _rootPartitionKey)))
.Remap(_ => UnitValue.None);
public ResultBox<UnitValue> AppendEvents(params IEventPayloadApplicableTo<TAggregatePayload>[] eventPayloads) =>
ResultBox.FromValue(eventPayloads.ToList()).ReduceEach(UnitValue.Unit, (nextEventPayload, _) => AppendEvent(nextEventPayload));
public Task<ResultBox<AggregateState<TAnotherAggregatePayload>>> GetAggregateState<TAnotherAggregatePayload>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public ResultBox<UnitValue> AppendEvent(IEventPayloadApplicableTo<TAggregatePayl
_rootPartitionKey,
eventPayload)))
.Remap(_ => UnitValue.None);
public ResultBox<UnitValue> AppendEvents(params IEventPayloadApplicableTo<TAggregatePayload>[] eventPayloads) =>
ResultBox.FromValue(eventPayloads.ToList()).ReduceEach(UnitValue.Unit, (nextEventPayload, _) => AppendEvent(nextEventPayload));
public async Task<ResultBox<CommandResponse>> HandleCommandAsync(
CommandDocument<TCommand> commandDocument,
Guid aggregateId,
Expand Down
61 changes: 0 additions & 61 deletions src/Sekiban.Core/ISekibanExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.Extensions.DependencyInjection;
using ResultBoxes;
using Sekiban.Core.Aggregate;
using Sekiban.Core.Command;
Expand Down Expand Up @@ -52,63 +51,3 @@ public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingl

public Task<ResultBox<TOutput>> ExecuteQuery<TOutput>(IQueryInput<TOutput> param) where TOutput : IQueryResponse;
}
public class SekibanExecutor(
ICommandExecutor commandExecutor,
IAggregateLoader aggregateLoader,
IQueryExecutor queryExecutor,
IServiceProvider serviceProvider) : ISekibanExecutor
{
public ResultBox<T1> GetRequiredService<T1>() where T1 : class => ResultBox.WrapTry(serviceProvider.GetRequiredService<T1>);

public Task<ResultBox<CommandExecutorResponse>> ExecuteCommand<TCommand>(TCommand command, List<CallHistory>? callHistories = null)
where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithResultAsync(command, callHistories);
public Task<ResultBox<CommandExecutorResponse>> ExecuteCommandWithoutValidation<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithoutValidationWithResultAsync(command, callHistories);
public Task<ResultBox<CommandExecutorResponseWithEvents>> ExecuteCommandWithoutValidationWithEvents<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithoutValidationWithEventsWithResultAsync(command, callHistories);

public Task<ResultBox<CommandExecutorResponseWithEvents>> ExecuteCommandWithEvents<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithEventsWithResultAsync(command, callHistories);

public Task<ResultBox<AggregateState<TAggregatePayloadCommon>>> GetAggregateState<TAggregatePayloadCommon>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null,
SingleProjectionRetrievalOptions? retrievalOptions = null) where TAggregatePayloadCommon : IAggregatePayloadCommon =>
aggregateLoader.AsDefaultStateWithResultAsync<TAggregatePayloadCommon>(aggregateId, rootPartitionKey, toVersion, retrievalOptions);

public Task<ResultBox<AggregateState<TAggregatePayloadCommon>>> GetAggregateStateFromInitial<TAggregatePayloadCommon>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null) where TAggregatePayloadCommon : IAggregatePayloadCommon =>
aggregateLoader.AsDefaultStateFromInitialWithResultAsync<TAggregatePayloadCommon>(aggregateId, rootPartitionKey, toVersion);

public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingleProjectionStateFromInitial<TSingleProjectionPayload>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null) where TSingleProjectionPayload : class, ISingleProjectionPayloadCommon =>
ResultBox.CheckNullWrapTry(
() => aggregateLoader.AsSingleProjectionStateFromInitialAsync<TSingleProjectionPayload>(aggregateId, rootPartitionKey, toVersion));
public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingleProjectionState<TSingleProjectionPayload>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null,
SingleProjectionRetrievalOptions? retrievalOptions = null) where TSingleProjectionPayload : class, ISingleProjectionPayloadCommon =>
ResultBox.CheckNullWrapTry(
() => aggregateLoader.AsSingleProjectionStateAsync<TSingleProjectionPayload>(aggregateId, rootPartitionKey, toVersion, retrievalOptions));
public Task<ResultBox<TOutput>> ExecuteQuery<TOutput>(INextQueryCommon<TOutput> query) where TOutput : notnull =>
queryExecutor.ExecuteAsync(query);
public Task<ResultBox<ListQueryResult<TOutput>>> ExecuteQuery<TOutput>(INextListQueryCommon<TOutput> query) where TOutput : notnull =>
queryExecutor.ExecuteAsync(query);
public Task<ResultBox<ListQueryResult<TOutput>>> ExecuteQuery<TOutput>(IListQueryInput<TOutput> param) where TOutput : IQueryResponse =>
queryExecutor.ExecuteWithResultAsync(param);
public Task<ResultBox<TOutput>> ExecuteQuery<TOutput>(IQueryInput<TOutput> param) where TOutput : IQueryResponse =>
queryExecutor.ExecuteWithResultAsync(param);
}
4 changes: 2 additions & 2 deletions src/Sekiban.Core/Sekiban.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
<PackageId>Sekiban.Core</PackageId>
<Version>0.20.1</Version>
<Version>0.20.2</Version>
<Authors>J-Tech Group</Authors>
<Company>J-Tech-Japan</Company>
<PackageDescription>Sekiban - Event Sourcing Framework Core</PackageDescription>
<RepositoryUrl>https://github.com/J-Tech-Japan/Sekiban</RepositoryUrl>
<PackageVersion>0.20.1</PackageVersion>
<PackageVersion>0.20.2</PackageVersion>
<Description>Web Authorization Check become async Task</Description>
<AssemblyName>Sekiban.Core</AssemblyName>
<RootNamespace>Sekiban.Core</RootNamespace>
Expand Down
70 changes: 70 additions & 0 deletions src/Sekiban.Core/SekibanExecutor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using Microsoft.Extensions.DependencyInjection;
using ResultBoxes;
using Sekiban.Core.Aggregate;
using Sekiban.Core.Command;
using Sekiban.Core.Documents;
using Sekiban.Core.History;
using Sekiban.Core.Query.QueryModel;
using Sekiban.Core.Query.SingleProjections;
namespace Sekiban.Core;

public class SekibanExecutor(
ICommandExecutor commandExecutor,
IAggregateLoader aggregateLoader,
IQueryExecutor queryExecutor,
IServiceProvider serviceProvider) : ISekibanExecutor
{
public ResultBox<T1> GetRequiredService<T1>() where T1 : class => ResultBox.WrapTry(serviceProvider.GetRequiredService<T1>);

public Task<ResultBox<CommandExecutorResponse>> ExecuteCommand<TCommand>(TCommand command, List<CallHistory>? callHistories = null)
where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithResultAsync(command, callHistories);
public Task<ResultBox<CommandExecutorResponse>> ExecuteCommandWithoutValidation<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithoutValidationWithResultAsync(command, callHistories);
public Task<ResultBox<CommandExecutorResponseWithEvents>> ExecuteCommandWithoutValidationWithEvents<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithoutValidationWithEventsWithResultAsync(command, callHistories);

public Task<ResultBox<CommandExecutorResponseWithEvents>> ExecuteCommandWithEvents<TCommand>(
TCommand command,
List<CallHistory>? callHistories = null) where TCommand : ICommandCommon =>
commandExecutor.ExecCommandWithEventsWithResultAsync(command, callHistories);

public Task<ResultBox<AggregateState<TAggregatePayloadCommon>>> GetAggregateState<TAggregatePayloadCommon>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null,
SingleProjectionRetrievalOptions? retrievalOptions = null) where TAggregatePayloadCommon : IAggregatePayloadCommon =>
aggregateLoader.AsDefaultStateWithResultAsync<TAggregatePayloadCommon>(aggregateId, rootPartitionKey, toVersion, retrievalOptions);

public Task<ResultBox<AggregateState<TAggregatePayloadCommon>>> GetAggregateStateFromInitial<TAggregatePayloadCommon>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null) where TAggregatePayloadCommon : IAggregatePayloadCommon =>
aggregateLoader.AsDefaultStateFromInitialWithResultAsync<TAggregatePayloadCommon>(aggregateId, rootPartitionKey, toVersion);

public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingleProjectionStateFromInitial<TSingleProjectionPayload>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null) where TSingleProjectionPayload : class, ISingleProjectionPayloadCommon =>
ResultBox.CheckNullWrapTry(
() => aggregateLoader.AsSingleProjectionStateFromInitialAsync<TSingleProjectionPayload>(aggregateId, rootPartitionKey, toVersion));
public Task<ResultBox<SingleProjectionState<TSingleProjectionPayload>>> GetSingleProjectionState<TSingleProjectionPayload>(
Guid aggregateId,
string rootPartitionKey = IDocument.DefaultRootPartitionKey,
int? toVersion = null,
SingleProjectionRetrievalOptions? retrievalOptions = null) where TSingleProjectionPayload : class, ISingleProjectionPayloadCommon =>
ResultBox.CheckNullWrapTry(
() => aggregateLoader.AsSingleProjectionStateAsync<TSingleProjectionPayload>(aggregateId, rootPartitionKey, toVersion, retrievalOptions));
public Task<ResultBox<TOutput>> ExecuteQuery<TOutput>(INextQueryCommon<TOutput> query) where TOutput : notnull =>
queryExecutor.ExecuteAsync(query);
public Task<ResultBox<ListQueryResult<TOutput>>> ExecuteQuery<TOutput>(INextListQueryCommon<TOutput> query) where TOutput : notnull =>
queryExecutor.ExecuteAsync(query);
public Task<ResultBox<ListQueryResult<TOutput>>> ExecuteQuery<TOutput>(IListQueryInput<TOutput> param) where TOutput : IQueryResponse =>
queryExecutor.ExecuteWithResultAsync(param);
public Task<ResultBox<TOutput>> ExecuteQuery<TOutput>(IQueryInput<TOutput> param) where TOutput : IQueryResponse =>
queryExecutor.ExecuteWithResultAsync(param);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Sekiban.Infrastructure.Aws.S3</PackageId>
<Version>0.20.1</Version>
<Version>0.20.2</Version>
<Authors>J-Tech Group</Authors>
<Company>J-Tech-Japan</Company>
<PackageDescription>Sekiban - Event Sourcing Framework AWS S3 Infrastructure</PackageDescription>
<RepositoryUrl>https://github.com/J-Tech-Japan/Sekiban</RepositoryUrl>
<PackageVersion>0.20.1</PackageVersion>
<PackageVersion>0.20.2</PackageVersion>
<Description>Web Authorization Check become async Task</Description>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>preview</LangVersion>
Expand All @@ -22,7 +22,7 @@
<ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="3.7.309.7"/>
<PackageReference Include="SharpZipLib" Version="1.4.2"/>
<PackageReference Include="Sekiban.Core" Version="0.20.1"/>
<PackageReference Include="Sekiban.Core" Version="0.20.2"/>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0"/>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Sekiban.Infrastructure.Azure.Storage.Blobs</PackageId>
<Version>0.20.1</Version>
<Version>0.20.2</Version>
<Authors>J-Tech Group</Authors>
<Company>J-Tech-Japan</Company>
<PackageDescription>Sekiban - Event Sourcing Framework Azure Storage Blob</PackageDescription>
<RepositoryUrl>https://github.com/J-Tech-Japan/Sekiban</RepositoryUrl>
<PackageVersion>0.20.1</PackageVersion>
<PackageVersion>0.20.2</PackageVersion>
<Description>Web Authorization Check become async Task</Description>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>preview</LangVersion>
Expand All @@ -24,7 +24,7 @@
<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
<PackageReference Include="Azure.Storage.Blobs" Version="12.20.0" />
<PackageReference Include="Sekiban.Core" Version="0.20.1"/>
<PackageReference Include="Sekiban.Core" Version="0.20.2"/>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0"/>
</ItemGroup>

Expand Down
Loading

0 comments on commit 1fdc04e

Please sign in to comment.