diff --git a/DFlow.sln b/DFlow.sln
index 5f51969..8df2dcf 100644
--- a/DFlow.sln
+++ b/DFlow.sln
@@ -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
@@ -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
@@ -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}
diff --git a/src/DFlow.Persistence/DFlow.Persistence.csproj b/src/DFlow.Persistence/DFlow.Persistence.csproj
index ff3d45e..4db1cd4 100644
--- a/src/DFlow.Persistence/DFlow.Persistence.csproj
+++ b/src/DFlow.Persistence/DFlow.Persistence.csproj
@@ -1,7 +1,16 @@
true
- 10
- enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/DFlow.Persistence/Model/AggregateState.cs b/src/DFlow.Persistence/Model/AggregateState.cs
new file mode 100644
index 0000000..a10d0ba
--- /dev/null
+++ b/src/DFlow.Persistence/Model/AggregateState.cs
@@ -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();
+ }
+}
\ No newline at end of file
diff --git a/src/DFlow.Persistence/Model/IsExternalInit.cs b/src/DFlow.Persistence/Model/IsExternalInit.cs
new file mode 100644
index 0000000..695b61d
--- /dev/null
+++ b/src/DFlow.Persistence/Model/IsExternalInit.cs
@@ -0,0 +1,4 @@
+namespace System.Runtime.CompilerServices
+{
+ internal static class IsExternalInit {}
+}
\ No newline at end of file
diff --git a/src/DFlow.Persistence/Model/PersistentState.cs b/src/DFlow.Persistence/Model/PersistentState.cs
index d9aadb6..e130251 100644
--- a/src/DFlow.Persistence/Model/PersistentState.cs
+++ b/src/DFlow.Persistence/Model/PersistentState.cs
@@ -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; }
- }
-}
\ No newline at end of file
+ public Guid PersistenceId { get; set; }
+}
diff --git a/src/DFlow.Persistence/Outbox/IEventsExporting.cs b/src/DFlow.Persistence/Outbox/IEventsExporting.cs
new file mode 100644
index 0000000..e262d4b
--- /dev/null
+++ b/src/DFlow.Persistence/Outbox/IEventsExporting.cs
@@ -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 ToOutBox(IDomainEvents entity);
+}
diff --git a/src/DFlow.Persistence/Repositories/IRepository.cs b/src/DFlow.Persistence/Repositories/IRepository.cs
index 4a5a073..ae227b3 100644
--- a/src/DFlow.Persistence/Repositories/IRepository.cs
+++ b/src/DFlow.Persistence/Repositories/IRepository.cs
@@ -6,10 +6,9 @@
using System.Threading.Tasks;
-namespace DFlow.Persistence.Repositories
+namespace DFlow.Persistence.Repositories;
+
+public interface IRepository : IRepositoryAppendOnly
{
- public interface IRepository: IRepositoryAppendOnly
- {
- Task Remove(TModel entity);
- }
-}
\ No newline at end of file
+ Task Remove(TModel entity);
+}
diff --git a/src/DFlow.Persistence/Repositories/IRepositoryAppendOnly.cs b/src/DFlow.Persistence/Repositories/IRepositoryAppendOnly.cs
index 4603c91..499b572 100644
--- a/src/DFlow.Persistence/Repositories/IRepositoryAppendOnly.cs
+++ b/src/DFlow.Persistence/Repositories/IRepositoryAppendOnly.cs
@@ -11,11 +11,12 @@
using System.Threading;
using System.Threading.Tasks;
-namespace DFlow.Persistence.Repositories
+namespace DFlow.Persistence.Repositories;
+
+public interface IRepositoryAppendOnly
{
- public interface IRepositoryAppendOnly
- {
- Task Add(TModel entity);
- Task> FindAsync(Expression> predicate, CancellationToken cancellationToken);
- }
+ Task Add(TModel entity);
+
+ Task> FindAsync(Expression> predicate,
+ CancellationToken cancellationToken);
}
\ No newline at end of file
diff --git a/src/DFlow/Aggregates/AggregateBase.cs b/src/DFlow/Aggregates/AggregateBase.cs
index c0a7968..feb0f4d 100644
--- a/src/DFlow/Aggregates/AggregateBase.cs
+++ b/src/DFlow/Aggregates/AggregateBase.cs
@@ -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:BaseValidation,
IAggregate where TChange: EntityBase
diff --git a/src/DFlow/BusinessObjects/AggregateId.cs b/src/DFlow/BusinessObjects/AggregateId.cs
new file mode 100644
index 0000000..9a1fe07
--- /dev/null
+++ b/src/DFlow/BusinessObjects/AggregateId.cs
@@ -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
+ {
+ public static AggregateId Empty()
+ {
+ return From(Guid.Empty);
+ }
+
+ public static AggregateId New()
+ {
+ return From(Guid.NewGuid());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DFlow/BusinessObjects/EntityBase.cs b/src/DFlow/BusinessObjects/EntityBase.cs
index 61cab0a..100c86e 100644
--- a/src/DFlow/BusinessObjects/EntityBase.cs
+++ b/src/DFlow/BusinessObjects/EntityBase.cs
@@ -12,63 +12,61 @@
using DFlow.Events;
using DFlow.Validation;
-namespace DFlow.BusinessObjects
+namespace DFlow.BusinessObjects;
+
+public abstract class EntityBase : BaseValidation,
+ IEntityIdentity, IDomainEvents
{
- public abstract class EntityBase: BaseValidation,
- IEntityIdentity
+ private readonly IList _events = new List();
+
+ protected EntityBase(TIdentity identity, VersionId version)
{
- private readonly IList _events = new List();
-
- 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 GetEvents()
- {
- return this._events.ToImmutableList();
- }
+ public VersionId Version { get; }
-
- public override string ToString()
- {
- return $"[ENTITY]:[IDENTITY: {Identity}]";
- }
-
- protected abstract IEnumerable