Skip to content

Commit

Permalink
more domain related code:
Browse files Browse the repository at this point in the history
- refactory of Entity domain events support
- aggregate to consume events from Entity
- major refactoring of Persistence to support Outbox
  • Loading branch information
drr00t committed Feb 5, 2023
1 parent 0615a79 commit 0fb67ee
Show file tree
Hide file tree
Showing 30 changed files with 465 additions and 189 deletions.
21 changes: 10 additions & 11 deletions DFlow.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DFlow.Persistence", "src\DF
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFlow.Testing", "tests\DFlow.Testing\DFlow.Testing.csproj", "{8AA5683F-E4E6-4D43-95C1-30F7F5C1C301}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFlow.Profiling", "tests\DFlow.NBench\DFlow.Profiling.csproj", "{497760E7-D2AB-448E-B098-5054F898B506}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFlow", "src\DFlow\DFlow.csproj", "{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFlow.Persistence.Aggregates", "src\DFlow.Persistence.Aggregates\DFlow.Persistence.Aggregates.csproj", "{850C6B16-1FCB-4127-868D-A295A74A4F30}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -37,14 +37,6 @@ Global
{8AA5683F-E4E6-4D43-95C1-30F7F5C1C301}.Release|Any CPU.Build.0 = Release|Any CPU
{8AA5683F-E4E6-4D43-95C1-30F7F5C1C301}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
{8AA5683F-E4E6-4D43-95C1-30F7F5C1C301}.Tests|Any CPU.Build.0 = Debug|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Debug|Any CPU.Build.0 = Debug|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Release Profilling|Any CPU.ActiveCfg = Release Profilling|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Release Profilling|Any CPU.Build.0 = Release Profilling|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Release|Any CPU.ActiveCfg = Release|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Release|Any CPU.Build.0 = Release|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
{497760E7-D2AB-448E-B098-5054F898B506}.Tests|Any CPU.Build.0 = Debug|Any CPU
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Release Profilling|Any CPU.ActiveCfg = Release Profilling|Any CPU
Expand All @@ -53,13 +45,20 @@ Global
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Release|Any CPU.Build.0 = Release|Any CPU
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
{3008E7CA-82EF-4FEC-BB5A-5098DC63BD37}.Tests|Any CPU.Build.0 = Debug|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Release Profilling|Any CPU.ActiveCfg = Release Profilling|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Release Profilling|Any CPU.Build.0 = Release Profilling|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Release|Any CPU.Build.0 = Release|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Tests|Any CPU.ActiveCfg = Debug|Any CPU
{850C6B16-1FCB-4127-868D-A295A74A4F30}.Tests|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8AA5683F-E4E6-4D43-95C1-30F7F5C1C301} = {1D9940E4-09D4-42B9-B72D-2DA4D1AA00EB}
{497760E7-D2AB-448E-B098-5054F898B506} = {1D9940E4-09D4-42B9-B72D-2DA4D1AA00EB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {95BFE15C-2D7D-47F7-8108-AAD1B212E52D}
Expand Down
13 changes: 11 additions & 2 deletions src/DFlow.Persistence/DFlow.Persistence.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<PackageVersion />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NodaTime" Version="3.1.6" />
<PackageReference Include="System.Memory.Data" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DFlow\DFlow.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Aggregates" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions src/DFlow.Persistence/Model/AggregateState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2020 Road to Agility
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.


using System;
using System.Text.Json;
using NodaTime;

namespace DFlow.Persistence.Model;

public sealed record AggregateState(Guid Id
, Guid AggregateId
, string AggregationType
, string EventType
, Instant EventDatetime
, JsonDocument EventData):IDisposable
{
public void Dispose()
{
EventData.Dispose();
}
}
4 changes: 4 additions & 0 deletions src/DFlow.Persistence/Model/IsExternalInit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit {}
}
26 changes: 12 additions & 14 deletions src/DFlow.Persistence/Model/PersistentState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@


using System;
namespace DFlow.Persistence.Model;

namespace DFlow.Persistence.Model
public abstract class PersistentState : IPersistentState
{
public abstract class PersistentState : IPersistentState
protected PersistentState(DateTime createAt, byte[] rowVersion)
{
protected PersistentState(DateTime createAt, byte[] rowVersion)
{
PersistenceId = Guid.NewGuid();
CreateAt = createAt;
RowVersion = rowVersion;
}
PersistenceId = Guid.NewGuid();
CreateAt = createAt;
RowVersion = rowVersion;
}

public DateTime CreateAt { get; set; }
public DateTime CreateAt { get;}

public byte[] RowVersion { get; set; }
public bool IsDeleted { get; set; }
public byte[] RowVersion { get; }
public bool IsDeleted { get; set; }

public Guid PersistenceId { get; set; }
}
}
public Guid PersistenceId { get; set; }
}
17 changes: 17 additions & 0 deletions src/DFlow.Persistence/Outbox/IEventsExporting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (C) 2023 Road to Agility
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.


using System.Collections.Generic;
using DFlow.BusinessObjects;
using DFlow.Persistence.Model;

namespace DFlow.Persistence.Outbox;

interface IEventsExporting
{
IReadOnlyList<AggregateState> ToOutBox(IDomainEvents entity);
}
11 changes: 5 additions & 6 deletions src/DFlow.Persistence/Repositories/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

using System.Threading.Tasks;

namespace DFlow.Persistence.Repositories
namespace DFlow.Persistence.Repositories;

public interface IRepository<TState, TModel> : IRepositoryAppendOnly<TState, TModel>
{
public interface IRepository<TState,TModel>: IRepositoryAppendOnly<TState,TModel>
{
Task Remove(TModel entity);
}
}
Task Remove(TModel entity);
}
13 changes: 7 additions & 6 deletions src/DFlow.Persistence/Repositories/IRepositoryAppendOnly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
using System.Threading;
using System.Threading.Tasks;

namespace DFlow.Persistence.Repositories
namespace DFlow.Persistence.Repositories;

public interface IRepositoryAppendOnly<TState, TModel>
{
public interface IRepositoryAppendOnly<TState,TModel>
{
Task Add(TModel entity);
Task<IReadOnlyList<TModel>> FindAsync(Expression<Func<TState, bool>> predicate, CancellationToken cancellationToken);
}
Task Add(TModel entity);

Task<IReadOnlyList<TModel>> FindAsync(Expression<Func<TState, bool>> predicate,
CancellationToken cancellationToken);
}
3 changes: 1 addition & 2 deletions src/DFlow/Aggregates/AggregateBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using DFlow.Aggregates;
using DFlow.BusinessObjects;
using DFlow.Events;
using DFlow.Validation;

namespace DFlow.Domain.Aggregates
namespace DFlow.Aggregates
{
public abstract class AggregateBase<TChange, TEntityId>:BaseValidation,
IAggregate<TChange> where TChange: EntityBase<TEntityId>
Expand Down
23 changes: 23 additions & 0 deletions src/DFlow/BusinessObjects/AggregateId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2022 Road to Agility
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using System;

namespace DFlow.BusinessObjects
{
public sealed class AggregateId : ValueOf<Guid, AggregateId>
{
public static AggregateId Empty()
{
return From(Guid.Empty);
}

public static AggregateId New()
{
return From(Guid.NewGuid());
}
}
}
88 changes: 43 additions & 45 deletions src/DFlow/BusinessObjects/EntityBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,63 +12,61 @@
using DFlow.Events;
using DFlow.Validation;

namespace DFlow.BusinessObjects
namespace DFlow.BusinessObjects;

public abstract class EntityBase<TIdentity> : BaseValidation,
IEntityIdentity<TIdentity>, IDomainEvents
{
public abstract class EntityBase<TIdentity>: BaseValidation,
IEntityIdentity<TIdentity>
private readonly IList<DomainEvent> _events = new List<DomainEvent>();

protected EntityBase(TIdentity identity, VersionId version)
{
private readonly IList<DomainEvent> _events = new List<DomainEvent>();

protected EntityBase(TIdentity identity, VersionId version)
{
Identity = identity;
Version = version;
}

public TIdentity Identity { get; }

public VersionId Version { get; }
Identity = identity;
Version = version;
}

public bool IsNew() => Version.IsNew;
public TIdentity Identity { get; }

public void RaisedEvent(DomainEvent @event)
{
this._events.Add(@event);
}

public IReadOnlyList<DomainEvent> GetEvents()
{
return this._events.ToImmutableList();
}
public VersionId Version { get; }


public override string ToString()
{
return $"[ENTITY]:[IDENTITY: {Identity}]";
}

protected abstract IEnumerable<object> GetEqualityComponents();
public bool IsNew() => Version.IsNew;

public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
public void RaisedEvent(DomainEvent @event)
{
this._events.Add(@event);
}

if (GetType() != obj.GetType())
{
return false;
}
public IReadOnlyList<DomainEvent> GetEvents()
{
return this._events.ToImmutableList();
}

var entity = (EntityBase<TIdentity>)obj;
public override string ToString()
{
return $"[ENTITY]:[IDENTITY: {Identity}]";
}

protected abstract IEnumerable<object> GetEqualityComponents();

return GetEqualityComponents().SequenceEqual(entity.GetEqualityComponents());
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}

public override int GetHashCode()
if (GetType() != obj.GetType())
{
return HashCode.Combine(GetEqualityComponents());
return false;
}

var entity = (EntityBase<TIdentity>)obj;

return GetEqualityComponents().SequenceEqual(entity.GetEqualityComponents());
}

public override int GetHashCode()
{
return HashCode.Combine(GetEqualityComponents());
}
}
23 changes: 23 additions & 0 deletions src/DFlow/BusinessObjects/EntityId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2022 Road to Agility
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

using System;

namespace DFlow.BusinessObjects
{
public sealed class EntityId : ValueOf<Guid, EntityId>
{
public static EntityId Empty()
{
return From(Guid.Empty);
}

public static EntityId New()
{
return From(Guid.NewGuid());
}
}
}
4 changes: 2 additions & 2 deletions src/DFlow/DFlow.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<PropertyGroup>
<Configurations>Debug;Release;Release Profilling</Configurations>
<Platforms>AnyCPU</Platforms>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageReference Include="System.Collections.Immutable" Version="7.0.0" />
<PackageReference Include="ValueOf" Version="2.0.21" />
</ItemGroup>
<PropertyGroup>
Expand Down
Loading

0 comments on commit 0fb67ee

Please sign in to comment.