Shirubasoft.Aspire.ModularAppHosts 4.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Shirubasoft.Aspire.ModularAppHosts --version 4.2.0
                    
NuGet\Install-Package Shirubasoft.Aspire.ModularAppHosts -Version 4.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Shirubasoft.Aspire.ModularAppHosts" Version="4.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shirubasoft.Aspire.ModularAppHosts" Version="4.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Shirubasoft.Aspire.ModularAppHosts" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Shirubasoft.Aspire.ModularAppHosts --version 4.2.0
                    
#r "nuget: Shirubasoft.Aspire.ModularAppHosts, 4.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Shirubasoft.Aspire.ModularAppHosts@4.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Shirubasoft.Aspire.ModularAppHosts&version=4.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Shirubasoft.Aspire.ModularAppHosts&version=4.2.0
                    
Install as a Cake Tool

Shirubasoft.Aspire.ModularAppHosts

Define an Aspire resource graph once and reuse it across AppHosts. A module can be added from the current application, imported from a managed Git checkout, and exposed through a generated strongly typed API. Importing does not load a module definition from Git: every consumer references the producer-owned C# contract package, while the configured repository supplies only the source and build context needed to materialize that contract.

Packages

Package Use it for
Shirubasoft.Aspire.ModularAppHosts Defining, exporting, importing, and consuming modules in an AppHost.
Shirubasoft.Aspire.ModularAppHosts.Testing Running the same E2E tests against an AppHost or an Aspire-managed Docker Compose deployment.
Shirubasoft.Aspire.ModularAppHosts.Templates Scaffolding a runnable module contract with dotnet new aspire-module.
Shirubasoft.Aspire.ModularAppHosts.Tool Exporting immutable module preview manifests and dispatching cross-repository E2E workflows.

Install the core package in AppHosts and shared module contracts:

dotnet add package Shirubasoft.Aspire.ModularAppHosts

The testing package is optional. Keeping it separate means regular AppHosts do not acquire Aspire.Hosting.Testing or Docker hosting dependencies. Add it to both the AppHost that declares the test deployment environment and the test project that creates the deployment builder.

dotnet add package Shirubasoft.Aspire.ModularAppHosts.Testing

The runtime packages and tool target .NET 10, and the Aspire-facing packages require Aspire 13.4.6 or later. Their APIs use the Aspire.Hosting.ModularAppHosts namespace. They are licensed under the MIT License.

Quick start

Prerequisites are the .NET 10 SDK, Aspire CLI 13.4 or later, and a running Docker 28+ or Podman 5+ container runtime. In an existing AppHost or shared contract project, install the core package, install the item template, and scaffold a contract:

dotnet add package Shirubasoft.Aspire.ModularAppHosts
dotnet new install Shirubasoft.Aspire.ModularAppHosts.Templates
dotnet new aspire-module --name CatalogModule --moduleName catalog --namespace Catalog.Modules

Replace the generated CatalogModule.cs content with this runnable contract. The generator creates typed properties for its resources:

using Aspire.Hosting;
using Aspire.Hosting.ModularAppHosts;

namespace Catalog.Modules;

[GenerateDistributedApplicationModule(Name, Version = "1")]
public static partial class CatalogModule
{
    public const string Name = "catalog";
    public const string ApiResourceName = "catalog-api";

    public static void Define(IDistributedApplicationModuleBuilder module)
    {
        module.AddContainer(ApiResourceName, "nginx", "alpine")
            .Configure(container =>
                container.WithHttpEndpoint(targetPort: 80, name: "http"));
    }
}

Add the module and use its generated resources like ordinary Aspire resource builders:

var builder = DistributedApplication.CreateBuilder(args);

var catalog = await builder.AddCatalogModuleAsync();

builder.AddContainer("storefront", "nginx", "alpine")
    .WithReference(catalog.Api.GetEndpoint("http"))
    .WaitFor(catalog.Api);

await builder.Build().RunAsync();

From the AppHost directory, run aspire run, open the dashboard URL printed by Aspire, and use the catalog-api endpoint to verify the module is running.

For a repository-backed module, supply its repository through configuration or WithRepository(...) and materialize it with await builder.ImportCatalogModuleAsync(). Packaged contracts can declare specialized projects with ModuleProjectPathBase.Repository, preserving local project debugging without coupling the contract to the consumer's source-tree layout. Import options can prefix or alias resources when a receiving AppHost already uses the contract names. The module guide covers repository-aware factories, project/container selection, identity, and image publishing.

Inside another module's Define method, CatalogModule.Reference(module) returns the same strongly typed API and validates the required contract version. Module definitions can read the AppHost's IConfiguration, use their conventional ConfigurationSection, or call GetOptions<T>() to bind IOptions<T> from Aspire:ModularAppHosts:Modules:<module-name>.

By default, local modules run as projects, imported modules run as containers, and existing clean imported repositories with a configured upstream are fast-forwarded before startup. Clean local branches without an upstream and dirty checkouts are left unchanged. Image build commands remain opt-in. Set UpdateImportedRepositories or a module's UpdateRepository to false to keep a checkout fixed, and use UseLocalModuleProjects(), UseModuleContainers(), or BuildModuleImages() for AppHost-wide intent.

Module image build commands can follow Aspire's Docker or Podman selection by awaiting ContainerRuntimeResolver.ResolveAsync(). It honors ASPIRE_CONTAINER_RUNTIME and the legacy DOTNET_ASPIRE_CONTAINER_RUNTIME variable, otherwise probes both runtimes in parallel and prefers one that is running. In publish mode, registry-backed module images participate in aspire do push; pass effective resource names after push to build or push only that subset, for example aspire do push catalog-api catalog-worker.

For a sibling-repository workflow, opt into AutoCloneRepositories. Same-worktree modules are discovered without a clone; a missing direct sibling is cloned with GitHub CLI. Published module images default to a branch-and-commit tag and add -dirty when their source worktree has changes. Registries can be modeled separately from image names, factory-created ContainerResource integrations can publish custom images without losing their typed APIs, missing clean images can be pulled before building, and legacy build outputs can be retagged without shell wrappers. Each exported project or container publisher can select a separate BuildRepository and revision, so a resource may be defined in an application contract while its Dockerfile and build script remain in an owning repository. Repositories can be pinned to a branch, tag, or commit, and existing checkouts are verified against the configured origin. The module guide documents the layout, configuration, and validation behavior.

For an ongoing feature branch that must be exercised by another repository's CI, install the local .NET tool, produce a request containing the clean pushed commit and any already-built image digests, then dispatch the consumer's trusted workflow:

dotnet tool install --global Shirubasoft.Aspire.ModularAppHosts.Tool
dotnet modular-apphosts preview produce \
  --descriptor module-preview.producer.json \
  --contract-version 2.3.0-preview.7 \
  --image catalog-api=ghcr.io/example/catalog/api@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
  --output module-preview.json
dotnet modular-apphosts preview trigger \
  --manifest module-preview.json \
  --repo example/end-to-end-tests \
  --workflow module-preview-e2e.yml \
  --ref main \
  --wait \
  --github-output "$GITHUB_OUTPUT"

The request carries full commits and OCI digests rather than mutable branch names and image tags. The producer descriptor may omit the contract for an image-only preview, or omit only its version and receive the exact CI-computed version through --contract-version. The consumer policy decides whether the contract is required and whether to restore its exact package from a reviewed HTTPS NuGet source or pack it from a reviewed source fallback. Published-package materialization does not check out or build the producer repository. A package feed is required only for requests that carry a contract.

The consumer tool checks its own policy and writes a trusted resolution for ApplyModulePreviewResolutionAsync. preview trigger prints workflow_run_id and workflow_run_url; --github-output appends them to a GitHub Actions output file, while a bare --wait returns the consumer run's final status. See the cross-repository preview guide for the complete security model, package-source and source-fallback boundaries, and runnable two-repository example.

Projects exported as containers can still run directly during local debugging. This changes run mode only; publishing continues to use the portable container representation:

{
  "Aspire": {
    "ModularAppHosts": {
      "Modules": {
        "catalog": {
          "Projects": {
            "catalog-api": {
              "ProjectMode": "Project"
            }
          }
        }
      }
    }
  }
}

Guides and samples

For repository setup, validation commands, and the release workflow, see Contributing.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Shirubasoft.Aspire.ModularAppHosts:

Package Downloads
Shirubasoft.Aspire.ModularAppHosts.Testing

Docker Compose deployment testing support for Shirubasoft Aspire Modular AppHosts.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
14.0.1 100 8/20/2026
14.0.0 96 8/19/2026
13.2.1 95 8/19/2026
13.2.0 121 8/18/2026
13.1.0 144 8/15/2026
13.0.0 239 8/14/2026
12.0.1 115 8/14/2026
12.0.0 123 8/14/2026
11.0.0 131 8/13/2026
10.0.1 118 8/12/2026
10.0.0 116 8/12/2026
9.0.0 116 8/11/2026
8.1.0 121 8/11/2026
8.0.0 128 8/11/2026
7.0.0 104 8/10/2026
6.0.0 112 8/8/2026
5.0.0 168 8/7/2026
4.3.0 131 8/7/2026
4.2.0 102 8/6/2026
4.1.0 104 8/6/2026
Loading failed