diff --git a/Chapter-4-applying-tactical-domain-driven-design/Directory.Build.props b/Chapter-4-applying-tactical-domain-driven-design/Directory.Build.props
new file mode 100644
index 00000000..faf2349b
--- /dev/null
+++ b/Chapter-4-applying-tactical-domain-driven-design/Directory.Build.props
@@ -0,0 +1,3 @@
+
+
+
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Directory.Packages.props b/Chapter-4-applying-tactical-domain-driven-design/Directory.Packages.props
new file mode 100644
index 00000000..6e28deb7
--- /dev/null
+++ b/Chapter-4-applying-tactical-domain-driven-design/Directory.Packages.props
@@ -0,0 +1,10 @@
+
+
+ true
+
+
+
+
+
+
+
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Fitnet.AppHost.csproj b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Fitnet.AppHost.csproj
new file mode 100644
index 00000000..7f5fd06d
--- /dev/null
+++ b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Fitnet.AppHost.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Program.cs b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Program.cs
new file mode 100644
index 00000000..19045535
--- /dev/null
+++ b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/Program.cs
@@ -0,0 +1,28 @@
+using Projects;
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+var postgres = builder.AddPostgres("postgres")
+ .WithImage("postgres", "14.3")
+ .WithPgAdmin();
+
+var fitnetDatabase = postgres.AddDatabase("fitnetsdb", "fitnet");
+
+var rabbitmq = builder.AddRabbitMQ("rabbitmq")
+ .WithManagementPlugin();
+
+builder.AddProject("fitnet-modular-monolith")
+ .WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
+ .WithReference(fitnetDatabase, "Database__ConnectionString")
+ .WithReference(rabbitmq, "EventBus__ConnectionString")
+ .WaitFor(postgres)
+ .WaitFor(rabbitmq);
+
+builder.AddProject("fitnet-contracts-microservice")
+ .WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
+ .WithReference(fitnetDatabase, "Database__ConnectionString")
+ .WithReference(rabbitmq, "EventBus__ConnectionString")
+ .WaitFor(postgres)
+ .WaitFor(rabbitmq);
+
+await builder.Build().RunAsync();
\ No newline at end of file
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/appsettings.json b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/appsettings.json
new file mode 100644
index 00000000..7e1692a8
--- /dev/null
+++ b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.DistributedApplication": "Information"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Fitnet.Contracts/Src/Fitnet.Contracts.Infrastructure/EventBus/EventBusModule.cs b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.Contracts/Src/Fitnet.Contracts.Infrastructure/EventBus/EventBusModule.cs
index b9c03abf..51551002 100644
--- a/Chapter-4-applying-tactical-domain-driven-design/Fitnet.Contracts/Src/Fitnet.Contracts.Infrastructure/EventBus/EventBusModule.cs
+++ b/Chapter-4-applying-tactical-domain-driven-design/Fitnet.Contracts/Src/Fitnet.Contracts.Infrastructure/EventBus/EventBusModule.cs
@@ -23,7 +23,23 @@ internal static IServiceCollection AddEventBus(this IServiceCollection services,
{
return;
}
-
+ var uri = options.Value?.Uri;
+ var username = options.Value?.Username;
+ var password = options.Value?.Password;
+ if (!string.IsNullOrEmpty(uri))
+ {
+ factoryConfigurator.Host(uri, h =>
+ {
+ if (!string.IsNullOrEmpty(username))
+ {
+ h.Username(username);
+ }
+ if (!string.IsNullOrEmpty(password))
+ {
+ h.Password(password);
+ }
+ });
+ }
factoryConfigurator.ConfigureEndpoints(context);
});
});
diff --git a/Chapter-4-applying-tactical-domain-driven-design/Fitnet/Src/Passes/Fitnet.Passes.Api/Common/EventBus/EventBusModule.cs b/Chapter-4-applying-tactical-domain-driven-design/Fitnet/Src/Passes/Fitnet.Passes.Api/Common/EventBus/EventBusModule.cs
index 5740084e..884aa8f6 100644
--- a/Chapter-4-applying-tactical-domain-driven-design/Fitnet/Src/Passes/Fitnet.Passes.Api/Common/EventBus/EventBusModule.cs
+++ b/Chapter-4-applying-tactical-domain-driven-design/Fitnet/Src/Passes/Fitnet.Passes.Api/Common/EventBus/EventBusModule.cs
@@ -26,6 +26,23 @@ internal static IServiceCollection AddEventBus(this IServiceCollection services,
{
return;
}
+ var uri = options.Value?.Uri;
+ var username = options.Value?.Username;
+ var password = options.Value?.Password;
+ if (!string.IsNullOrEmpty(uri))
+ {
+ factoryConfigurator.Host(uri, h =>
+ {
+ if (!string.IsNullOrEmpty(username))
+ {
+ h.Username(username);
+ }
+ if (!string.IsNullOrEmpty(password))
+ {
+ h.Password(password);
+ }
+ });
+ }
factoryConfigurator.ConfigureEndpoints(context);
});
configurator.ConfigureOutbox();
diff --git a/Chapter-4-applying-tactical-domain-driven-design/README.adoc b/Chapter-4-applying-tactical-domain-driven-design/README.adoc
index dd2d62a4..dd737765 100644
--- a/Chapter-4-applying-tactical-domain-driven-design/README.adoc
+++ b/Chapter-4-applying-tactical-domain-driven-design/README.adoc
@@ -374,6 +374,26 @@ The `Contracts` microservice runs on port `:8081`. Please navigate to http://loc
That's it! You should now be able to run the application using either one of the above. :thumbsup:
+=== Run with .NET Aspire
+
+The Fitnet application uses .NET Aspire for local development.
+
+To run the application locally using Aspire, follow these steps:
+
+1. **Ensure Docker is running** on your machine.
+2. **Navigate to the AppHost directory:**
+[source,shell]
+----
+cd Fitnet.AppHost
+----
+3. **Run the AppHost project:**
+[source,shell]
+----
+dotnet run
+----
+
+The Aspire Dashboard will open automatically, showing all services, resources, and logs.
+
=== Building and debugging code in Rider IDE
Before you build or debug code in `Rider` or `Visual Studio` IDE, you first have to provide your username and previously generated PAT for artifactory to download packages for `Common` which is a part of this repository. When you load the solution, your IDE should request the credentials: