Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Targeting .NET Standard 2.1 and various changes. #10

Merged
merged 21 commits into from
Jun 7, 2024
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
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

Nothing yet.
### Added

- Database migration tools.

### Changed

- `DomainEvent` is now a class, and uses an `EventId` struct.
- Using `ErrorMessageBuilder` in exceptions.
- Recreated scripts and migrations.
- Refactored the `LoadFromChanges<T>` method to remove Reflection.
- Core package now targets .NET Standard 2.1.
- `ToString` methods now include ID prefix.

### Fixed

- README files and migration commands.
- Docker Compose file.

## [5.2.0] - 2024-03-25

Expand Down
9 changes: 9 additions & 0 deletions EventSourcing.sln
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logitar.EventSourcing.Mongo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logitar.EventSourcing.MongoDB.IntegrationTests", "tests\Logitar.EventSourcing.MongoDB.IntegrationTests\Logitar.EventSourcing.MongoDB.IntegrationTests.csproj", "{CEEFD05A-DC09-4756-8473-527539E478F1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{9C6D5EFE-FF9F-4D87-B70B-916701A1CD6B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.EventSourcing.Database", "tools\Logitar.EventSourcing.Database\Logitar.EventSourcing.Database.csproj", "{7D816D68-A25C-466C-B1D1-5722AE64F9CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -161,6 +165,10 @@ Global
{CEEFD05A-DC09-4756-8473-527539E478F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CEEFD05A-DC09-4756-8473-527539E478F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CEEFD05A-DC09-4756-8473-527539E478F1}.Release|Any CPU.Build.0 = Release|Any CPU
{7D816D68-A25C-466C-B1D1-5722AE64F9CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D816D68-A25C-466C-B1D1-5722AE64F9CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D816D68-A25C-466C-B1D1-5722AE64F9CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D816D68-A25C-466C-B1D1-5722AE64F9CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -179,6 +187,7 @@ Global
{5FBFB540-E143-4C73-837E-5672E71D18B6} = {D092FA68-D3D5-460E-9A38-61033D6F9692}
{FD1A7AF8-FEDF-4EA1-9966-C46677584BB2} = {D092FA68-D3D5-460E-9A38-61033D6F9692}
{CEEFD05A-DC09-4756-8473-527539E478F1} = {D092FA68-D3D5-460E-9A38-61033D6F9692}
{7D816D68-A25C-466C-B1D1-5722AE64F9CB} = {9C6D5EFE-FF9F-4D87-B70B-916701A1CD6B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0AA9E53-02AD-4000-8ED5-53AFF5D1B32D}
Expand Down
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
version: '3.8'
name: event_sourcing
services:
event_sourcing_mongo:
image: mongo
container_name: Logitar.EventSourcing_mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: demo
MONGO_INITDB_ROOT_PASSWORD: AwHE5MRKBeY9CsJu
Expand All @@ -13,6 +13,7 @@ services:
event_sourcing_mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: Logitar.EventSourcing_mssql
restart: unless-stopped
environment:
ACCEPT_EULA: 'Y'
SA_PASSWORD: mWGEgJcrV5dzRyqb
Expand All @@ -22,6 +23,7 @@ services:
event_sourcing_postgres:
image: postgres
container_name: Logitar.EventSourcing_postgres
restart: unless-stopped
environment:
POSTGRES_PASSWORD: cptBg3hZ9qC6a5Vb
ports:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
EventId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Id = table.Column<Guid>(type: "uuid", nullable: false),
Id = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
ActorId = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: false),
IsDeleted = table.Column<bool>(type: "boolean", nullable: true),
OccurredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("ProductVersion", "8.0.6")
.HasAnnotation("Relational:MaxIdentifierLength", 63);

NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
Expand Down Expand Up @@ -53,8 +53,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(255)
.HasColumnType("character varying(255)");

b.Property<Guid>("Id")
.HasColumnType("uuid");
b.Property<string>("Id")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)");

b.Property<bool?>("IsDeleted")
.HasColumnType("boolean");
Expand Down
18 changes: 11 additions & 7 deletions src/Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL
# Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL

Provides an implementation of a relational event store to be used with the Event Sourcing
architecture pattern, Entity Framework Core and PostgreSQL.
Provides an implementation of a relational event store to be used with the Event Sourcing architecture pattern, Entity Framework Core and PostgreSQL.

## Migrations

This project is setup to use migrations. You must execute the following commands in the solution
directory.
This project is setup to use migrations. You must execute the following commands in the solution directory.

⚠️ Ensure the `EntityFrameworkCorePostgreSQL` database provider has been set in the database project user secrets.

### Create a new migration

Execute the following command to create a new migration. Do not forget to specify a migration name!

`dotnet ef migrations add <YOUR_MIGRATION_NAME> --context EventContext --project src/EventSourcing/Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL --startup-project src/Demo/Logitar.Demo.Ui`
```sh
dotnet ef migrations add <YOUR_MIGRATION_NAME> --context EventContext --project src/Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL --startup-project tools/Logitar.EventSourcing.Database
```

### Generate a script

Execute the following command to generate a new script. Do not forget to specify a source migration name!

`dotnet ef migrations script <FROM_MIGRATION_NAME> --context EventContext --project src/EventSourcing/Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL --startup-project src/Demo/Logitar.Demo.Ui`
```sh
dotnet ef migrations script <FROM_MIGRATION_NAME> --context EventContext --project src/Logitar.EventSourcing.EntityFrameworkCore.PostgreSQL --startup-project tools/Logitar.EventSourcing.Database
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ START TRANSACTION;

CREATE TABLE "Events" (
"EventId" bigint GENERATED BY DEFAULT AS IDENTITY,
"Id" uuid NOT NULL,
"Id" character varying(255) NOT NULL,
"ActorId" character varying(255) NOT NULL,
"IsDeleted" boolean NULL,
"IsDeleted" boolean,
"OccurredOn" timestamp with time zone NOT NULL,
"Version" bigint NOT NULL,
"AggregateType" character varying(255) NOT NULL,
Expand All @@ -37,6 +37,6 @@ CREATE INDEX "IX_Events_OccurredOn" ON "Events" ("OccurredOn");
CREATE INDEX "IX_Events_Version" ON "Events" ("Version");

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20230804163231_CreateEventTable', '7.0.9');
VALUES ('20240607013711_CreateEventTable', '8.0.6');

COMMIT;
COMMIT;
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ public void Configure(EntityTypeBuilder<EventEntity> builder)
builder.HasIndex(x => x.EventType);
builder.HasIndex(x => new { x.AggregateType, x.AggregateId });

builder.Property(x => x.ActorId).HasMaxLength(byte.MaxValue);
builder.Property(x => x.Id).IsRequired().HasMaxLength(EventId.MaximumLength);
builder.Property(x => x.ActorId).HasMaxLength(ActorId.MaximumLength);
builder.Property(x => x.AggregateType).HasMaxLength(byte.MaxValue);
builder.Property(x => x.AggregateId).HasMaxLength(byte.MaxValue);
builder.Property(x => x.AggregateId).HasMaxLength(AggregateId.MaximumLength);
builder.Property(x => x.EventType).HasMaxLength(byte.MaxValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public EventContext(DbContextOptions<EventContext> options) : base(options)
/// <summary>
/// Gets or sets the data set of events.
/// </summary>
public DbSet<EventEntity> Events { get; private set; } = null!;
public DbSet<EventEntity> Events { get; private set; }

/// <summary>
/// Configures the specified model builder.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private EventEntity()
/// <summary>
/// Gets or sets the identifier of the event.
/// </summary>
public Guid Id { get; private set; }
public string Id { get; private set; } = string.Empty;

/// <summary>
/// Gets or sets the identifier of the actor who triggered the event.
Expand Down Expand Up @@ -71,7 +71,7 @@ public static IEnumerable<EventEntity> FromChanges(AggregateRoot aggregate, IEve

return aggregate.Changes.Select(change => new EventEntity
{
Id = change.Id,
Id = change.Id.Value,
ActorId = change.ActorId.Value,
IsDeleted = change.IsDeleted,
OccurredOn = change.OccurredOn.ToUniversalTime(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Logitar.EventSourcing.EntityFrameworkCore.Relational

Provides an abstraction of a relational event store to be used with the Event Sourcing architecture
pattern and Entity Framework Core.
Provides an abstraction of a relational event store to be used with the Event Sourcing architecture pattern and Entity Framework Core.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
EventId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Id = table.Column<string>(type: "nvarchar(255)", maxLength: 255, nullable: false),
ActorId = table.Column<string>(type: "nvarchar(255)", maxLength: 255, nullable: false),
IsDeleted = table.Column<bool>(type: "bit", nullable: true),
OccurredOn = table.Column<DateTime>(type: "datetime2", nullable: false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("ProductVersion", "8.0.6")
.HasAnnotation("Relational:MaxIdentifierLength", 128);

SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
Expand Down Expand Up @@ -53,8 +53,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");

b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("Id")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("nvarchar(255)");

b.Property<bool?>("IsDeleted")
.HasColumnType("bit");
Expand Down
18 changes: 11 additions & 7 deletions src/Logitar.EventSourcing.EntityFrameworkCore.SqlServer/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# Logitar.EventSourcing.EntityFrameworkCore.SqlServer
# Logitar.EventSourcing.EntityFrameworkCore.SqlServer

Provides an implementation of a relational event store to be used with the Event Sourcing
architecture pattern, Entity Framework Core and Microsoft SQL Server.
Provides an implementation of a relational event store to be used with the Event Sourcing architecture pattern, Entity Framework Core and Microsoft SQL Server.

## Migrations

This project is setup to use migrations. You must execute the following commands in the solution
directory.
This project is setup to use migrations. You must execute the following commands in the solution directory.

⚠️ Ensure the `EntityFrameworkCoreSqlServer` database provider has been set in the database project user secrets.

### Create a new migration

Execute the following command to create a new migration. Do not forget to specify a migration name!

`dotnet ef migrations add <YOUR_MIGRATION_NAME> --context EventContext --project src/EventSourcing/Logitar.EventSourcing.EntityFrameworkCore.SqlServer --startup-project src/Demo/Logitar.Demo.Ui`
```sh
dotnet ef migrations add <YOUR_MIGRATION_NAME> --context EventContext --project src/Logitar.EventSourcing.EntityFrameworkCore.SqlServer --startup-project tools/Logitar.EventSourcing.Database
```

### Generate a script

Execute the following command to generate a new script. Do not forget to specify a source migration name!

`dotnet ef migrations script <FROM_MIGRATION_NAME> --context EventContext --project src/EventSourcing/Logitar.EventSourcing.EntityFrameworkCore.SqlServer --startup-project src/Demo/Logitar.Demo.Ui`
```sh
dotnet ef migrations script <FROM_MIGRATION_NAME> --context EventContext --project src/Logitar.EventSourcing.EntityFrameworkCore.SqlServer --startup-project tools/Logitar.EventSourcing.Database
```
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
Expand All @@ -13,7 +13,7 @@ GO

CREATE TABLE [Events] (
[EventId] bigint NOT NULL IDENTITY,
[Id] uniqueidentifier NOT NULL,
[Id] nvarchar(255) NOT NULL,
[ActorId] nvarchar(255) NOT NULL,
[IsDeleted] bit NULL,
[OccurredOn] datetime2 NOT NULL,
Expand Down Expand Up @@ -51,8 +51,8 @@ CREATE INDEX [IX_Events_Version] ON [Events] ([Version]);
GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20230804163434_CreateEventTable', N'7.0.9');
VALUES (N'20240607013010_CreateEventTable', N'8.0.6');
GO

COMMIT;
GO
GO
4 changes: 2 additions & 2 deletions src/Logitar.EventSourcing.InMemory/EventEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ private EventEntity()
{
}

public Guid Id { get; private set; }
public string Id { get; private set; } = string.Empty;

public long Version { get; private set; }

Expand All @@ -25,7 +25,7 @@ public static IEnumerable<EventEntity> FromChanges(AggregateRoot aggregate, IEve

return aggregate.Changes.Select(change => new EventEntity
{
Id = change.Id,
Id = change.Id.Value,
Version = change.Version,
AggregateType = aggregateType,
AggregateId = aggregateId,
Expand Down
Loading
Loading