App host shape
The primary app host wired up:
- The Vue.js front end (run via the front-end toolchain, hosted in Aspire as an external resource for orchestration purposes)
- The C# backend-for-frontend API (referenced .NET project)
- The progress engine API (referenced .NET project, pulled in via the sub-repository)
- Two Azure Functions for the OneFile ingestion and adapter layer (also via sub-repository)
- SQL Server (containerised)
- Azure Blob Storage emulator (containerised)
- Redis (containerised)
A second, slimmer app host stood up only the dashboard, the BFF API, and SQL, for developers working purely on dashboard concerns who did not need the progress engine or OneFile flows running locally.
Sub-repository commit pointer drift
The single sharpest edge in a multi-repo Aspire setup is what happens when developers commit code that spans more than one repository. If a feature branch in the dashboard repo references a feature branch in the progress engine repo (because the dashboard work depends on the progress engine work), the parent repo records the sub-repository pointer at that feature branch commit. When the progress engine feature branch is merged into main and deleted, the next developer who pulls latest in the dashboard repo finds the sub-repo pointing at a commit that no longer exists on a known branch.
The mitigation we settled on was a discipline rule rather than a tooling fix: sub-repositories should always point at long-lived branches in the parent repo's commits, not at short-lived feature branches. Cross-repo work needed a deliberate handshake: get the progress engine change into a long-lived branch first, then advance the dashboard repo's pointer to match. There is more tooling to be built here. I did not solve the problem on this engagement, only contained it.
Why not docker-compose
A reasonable question is why not just use docker-compose, which is the muscle-memory answer for this shape of system. The honest answer is that docker-compose is fine when the team is comfortable with it. With a predominantly junior team, including bootcamp graduates and developers new to the languages they were working in, the cost of debugging environment issues in YAML is much higher than the cost of debugging them in a typed C# app host where the IDE can help. Aspire also let me model service-to-service dependencies and connection strings as first-class, refactor-aware references rather than as strings duplicated across files. For this team, that mattered more than it would for a more senior group.
What I would do differently
If I were starting again I would invest earlier in a documented sub-repository workflow rather than letting the team discover the pointer drift problem in flight. I would also push harder, earlier, for the dashboard-only app host as the default for front-end work, rather than letting it become a thing people opted into when the full ecosystem felt heavy. Both are workflow questions rather than Aspire questions, but they are the two things I would tighten up next time.