Skip to content
Tutorial2/4

2. Create the System and run it

In this chapter you assemble the two Components into a System and run it end to end.

From the scratch directory root:

Terminal window
intropy sys create -n OrderNotifications --template-version v0.4.1
fetching integrio-intropy/intropy-templates@v0.4.1
created order-notifications from integrio-intropy/intropy-templates@v0.4.1 (template system-host)
assembled system "order-notifications": 2 component(s), 1 topic(s), 2 port(s), contracts from Contracts

intropy sys create reads before it writes: it scanned the workspace’s scaffold records, validated them into a system model, and rendered order-notifications/, the system host. The declaration it wrote is ordinary C#:

order-notifications/OrderNotificationsSystem.cs
public sealed class OrderNotificationsSystem : ISystemDefinition
{
public string SystemName => "order-notifications";
public void Define(SystemBuilder builder)
{
builder.AddExtractor("erp-extractor")
.From(Ports.ErpExtractorSource)
.Publishes(Topics.OrderNotifications)
.Uses(Services.Idempotency)
.Uses(Services.BusinessIncidents);
builder.AddLoader("wms-loader")
.Subscribes(Topics.OrderNotifications)
.To(Ports.WmsLoaderDestination)
.Uses(Services.Idempotency)
.Uses(Services.BusinessIncidents);
}
}

Read it against the diagram on the introduction page: every box and arrow is one call. The Topic is defined once in Topics.cs and both Components reference the same TopicRef; the Ports are defined in Ports.cs, and OrderNotificationsDevelopment.cs resolves each one to a local folder under test/. Chapter 3 edits all three files, so it’s worth skimming them now. The system host lists the full declaration surface.

You are about to seed and run this System several times, so wrap the two commands once. This creates Taskfile.yml at the workspace root, next to the component directories — paste it as one command:

Terminal window
cat > Taskfile.yml <<'EOF'
version: "3"
tasks:
seed:
desc: Drop the sample order into the extractor's source folder
dir: order-notifications
cmds:
- mkdir -p test/erp-extractor-source
- cp sample-data/sample-order.json test/erp-extractor-source/
- echo "seeded test/erp-extractor-source"
run:
desc: Run the system under the Aspire dashboard; stop with Ctrl+C
dir: order-notifications
cmds:
- dotnet run
EOF

seed copies the sample order the scaffold ships into the extractor’s source folder; run starts the host. The host directory carries its own generated Taskfile.yml with inspection verbs (check, graph); this one lives a level up and holds the two commands the tutorial repeats.

The extractor is a run-to-completion job: it sweeps its source folder once at host start, so seed before running. From the workspace root:

Terminal window
task seed
task run

The host translates the topology into Aspire resources: both Components as processes, a Dapr sidecar each, a Redis-backed broker, and the two platform services as OpenAPI mocks. Wait for the dashboard line and open the login URL it prints:

Login to the dashboard at http://localhost:15170/login?t=<token>

The Aspire dashboard shows every resource, its logs, and the distributed traces of the run. One host at a time: the dashboard ports are fixed, so stop a previous dotnet run (Ctrl+C) before starting another.

Within a few seconds of the components starting, the extractor sweeps the seeded file, publishes it to order-notifications, and the loader writes the transformed order to its destination folder:

Terminal window
cat order-notifications/test/wms-loader-destination/ORD-1001.json
{"OrderId":"ORD-1001","CustomerId":"CUST-42","LoadedAt":"2026-08-17T07:28:07.812399+00:00","Status":"Loaded"}

The source file is gone — swept — and the WMS folder holds the delivered order. Stop the host with Ctrl+C when you’ve seen it; chapter 3 works on the code, not the running system.