diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..cd967fc
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/.idea
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/README.md b/README.md
index 8b1bae1..4649745 100644
--- a/README.md
+++ b/README.md
@@ -47,35 +47,29 @@ Ideally on my birthday, May 22nd!
## 🏃 Running
-### 0️⃣ Project: StudentEnrollment00
+### 0️⃣1️⃣ StudentEnrollment01.InMemory
+
+#### AKA the in-memory event store version
Like the other programs that are .NET console application, the database is a glorified key-value store that's in-memory.
To run it, enter the project directory through your shell's associated Change Directory (`cd`) command from the solution root, such as:
```bash
-cd .\StudentEnrollment01
-```
-
-and then build the project
-
-```bash
+cd .\StudentEnrollment01.InMemory
dotnet build
-```
-
-and run it
-
-```bash
dotnet run
```
Alternatively, you can do all this from the solution's root by targeting the project with `--project` and `run` it immediately, such as:
```bash
-dotnet run --project .\StudentEnrollment00\StudentEnrollment00.csproj
+dotnet run --project .\StudentEnrollment01.InMemory\StudentEnrollment01.InMemory.csproj
```
-### 1️⃣ Project: StudentEnrollment01
+### 0️⃣2️⃣ StudentEnrollment02.Esdb
+
+#### AKA with EventStoreDB
While still a .NET console app, we're now going to use the Event Store database. So be sure to launch EventStoreDB through Docker. With a terminal / command prompt execute:
@@ -83,12 +77,14 @@ While still a .NET console app, we're now going to use the Event Store database.
docker-compose up
```
+**NOTE**: You will need to have ESDB running via Docker for the third (03) project as well.
+
Like before, you can change directory into the project or run it from the root.
Run the console application of your choice, change direction to that particular project directory and then execute:
```bash
-cd .\StudentEnrollment01
+cd .\StudentEnrollment02.Esdb
dotnet build
dotnet run
```
@@ -96,10 +92,12 @@ dotnet run
Or alternatively:
```bash
-dotnet run --project .\StudentEnrollment01\StudentEnrollment01.csproj
+dotnet run --project .\StudentEnrollment02.Esdb\StudentEnrollment02.Esdb.csproj
```
-### 2️⃣ TBD
+### 0️⃣3️⃣ StudentEnrollment03.Esdb
+
+#### AKA with EventStoreDB, plus a few changes
Instructions will go here, but will basically be the same as above!
diff --git a/StudentEnrollment01.InMemory/Dockerfile b/StudentEnrollment01.InMemory/Dockerfile
new file mode 100644
index 0000000..79c55d5
--- /dev/null
+++ b/StudentEnrollment01.InMemory/Dockerfile
@@ -0,0 +1,21 @@
+FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
+USER $APP_UID
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj", "StudentEnrollment01.InMemory/"]
+RUN dotnet restore "StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj"
+COPY . .
+WORKDIR "/src/StudentEnrollment01.InMemory"
+RUN dotnet build "StudentEnrollment01.InMemory.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "StudentEnrollment01.InMemory.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "StudentEnrollment01.InMemory.dll"]
diff --git a/StudentEnrollment01.InMemory/Program.cs b/StudentEnrollment01.InMemory/Program.cs
index d6a4c0c..d7f1858 100644
--- a/StudentEnrollment01.InMemory/Program.cs
+++ b/StudentEnrollment01.InMemory/Program.cs
@@ -22,6 +22,12 @@
"StudentId: {0}\nFullName: {1}\nEmail: {2}\nDateOfBirth: {3}\nCreatedAtUtc: {4}",
student!.Id, student.FullName, student.Email, student.DateOfBirth, student.CreatedAtUtc);
Console.WriteLine("Enrolled courses:");
+if (student.EnrolledCourses.Count is 0)
+{
+ Console.WriteLine("No enrolled courses");
+ return;
+}
+
foreach (var enrolledCourse in student.EnrolledCourses)
Console.WriteLine($"\t- {enrolledCourse}");
Console.WriteLine();
\ No newline at end of file
diff --git a/StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj b/StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj
index e407cdc..4fa8577 100644
--- a/StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj
+++ b/StudentEnrollment01.InMemory/StudentEnrollment01.InMemory.csproj
@@ -8,4 +8,10 @@
Linux
+
+
+ .dockerignore
+
+
+
diff --git a/StudentEnrollment02.Esdb/Program.cs b/StudentEnrollment02.Esdb/Program.cs
index fe4b0b7..0f02fb7 100644
--- a/StudentEnrollment02.Esdb/Program.cs
+++ b/StudentEnrollment02.Esdb/Program.cs
@@ -60,11 +60,14 @@ await client.AppendToStreamAsync(
);
if (await streamResult.ReadState is ReadState.StreamNotFound)
+{
+ Console.WriteLine($"The fetched stream (id: {streamId}) that was read was in StreamNotFound state");
return;
+}
var eventStream = await streamResult.ToListAsync();
-Console.WriteLine("Events from selected stream: ");
+Console.WriteLine($"Events (total: {eventStream.Count}) from selected stream: ");
foreach (var resolved in eventStream)
{
Console.WriteLine($"\tEventId: {resolved.Event.EventId}");
@@ -79,6 +82,6 @@ await client.AppendToStreamAsync(
.Select(re => JsonSerializer.Deserialize(re.Event.Data.ToArray()))
.Select(se => se!.CourseName)
.ToList();
-Console.WriteLine("Courses enrolled in: ");
-enrolledCourses.ForEach(ec => Console.WriteLine($"\t- {ec}"));
+Console.WriteLine("Enrolled courses found in the stream: ");
+enrolledCourses.ForEach(ec => Console.WriteLine($"\t- {ec}")); // run the app multiple times ;)
Console.WriteLine("");
\ No newline at end of file
diff --git a/StudentEnrollment03.Esdb/Program.cs b/StudentEnrollment03.Esdb/Program.cs
index f2caef9..ebb48d8 100644
--- a/StudentEnrollment03.Esdb/Program.cs
+++ b/StudentEnrollment03.Esdb/Program.cs
@@ -87,13 +87,15 @@
var settings = EventStoreClientSettings.Create(connectionString);
var client = new EventStoreClient(settings);
+// Append the initial batch of events.
await client.AppendToStreamAsync(
streamId,
StreamState.Any,
- new[] { created, enrolled, enrolled2, enrolled3, emailChanged, withdrawn },
+ new[] { created, enrolled, enrolled2, enrolled3, emailChanged },
cancellationToken: default
);
+// Read from the stream we just appended to.
var streamResult = client.ReadStreamAsync(
Direction.Forwards,
streamId,
@@ -101,12 +103,29 @@ await client.AppendToStreamAsync(
cancellationToken: default
);
+// Optional safety check, but here we're ensuring the stream was found.
if (await streamResult.ReadState is ReadState.StreamNotFound)
+{
+ Console.WriteLine($"The fetched stream (id: {streamId}) that was read was in StreamNotFound state");
return;
+}
+// Okay, taking that StreamResult we're going to make it a List of ResolvedEvents.
var eventStream = await streamResult.ToListAsync();
+// Get the last event's event number.
+var lastEventNumFromStream = eventStream.Last().Event.EventNumber.ToUInt64();
+
+// Append another event. This time let's make sure no one has appended to (AKA updated) the stream.
+await client.AppendToStreamAsync(
+ streamId,
+ new StreamRevision(lastEventNumFromStream), // checking against expected revision number
+ new[] { withdrawn },
+ cancellationToken: default
+);
+
var student = new Student();
+Console.WriteLine($"Events (total: {eventStream.Count}) from selected stream: ");
foreach (var @event in eventStream)
{
switch (DeserializeEvent(@event.Event))
diff --git a/docker-compose.yml b/docker-compose.yml
index cea2e4a..81a92cb 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,12 @@
version: "3.4"
services:
+ app01-inmemory:
+ build:
+ dockerfile: StudentEnrollment01.InMemory/Dockerfile
+ context: .
+ container_name: app01-inmemory
+
student-enrollment-esdb:
image: eventstore/eventstore:24.2.0-jammy
environment:
@@ -15,4 +21,5 @@ services:
networks:
- student-enrollment-esdb-net
networks:
- student-enrollment-esdb-net:
\ No newline at end of file
+ student-enrollment-esdb-net:
+ driver: bridge
\ No newline at end of file