Template-driven delivery sounds simple until you hit the question that breaks most attempts: when you scaffold a new project, are you producing the customer's code or the tooling that produces the customer's code? Confuse the two and factory internals leak into client repositories, or worse, customer-specific code contaminates your reusable templates. We resolve it with one explicit distinction - an artifact kind - that runs through everything.
Two kinds of artifact
Every generated thing is one of two kinds, chosen at scaffold time:
dotnet new connectsoft-service --artifact-kind solution -n Acme.Orders
dotnet new connectsoft-service --artifact-kind template -n Acme.Orders.Template
A solution is a concrete, runnable product - the actual service a customer will own, deploy, and extend. A template is reusable tooling - a parameterized starting point that, when invoked, produces solutions. The same underlying assets can render either way, but the output and its audience are completely different.
Why the distinction matters
The split exists to protect a boundary that is easy to violate:
- Solutions must not contain factory machinery. A customer's repository should not ship our generation scaffolding, internal placeholders, or template parameters. They get clean, idiomatic code that looks hand-written.
- Templates must not contain customer specifics. A template that accidentally bakes in one client's name, config, or domain logic is no longer reusable - it is a one-off pretending to be a template.
Keeping these apart by construction means you never have to clean factory residue out of a delivery, and you never have to scrub a customer's details out of a template before reusing it.
Note: The fastest way to ruin a template system is to let solutions and templates blur. Once factory internals appear in customer code even once, every consumer starts copying the contamination.
Layering makes it work
The distinction is enabled by layering. Shared behavior lives in base templates; specific templates compose on top. When you scaffold a solution, the layers render into final code with the parameters filled in and the scaffolding stripped. When you scaffold a template, the layers compose into a new reusable template with parameters preserved. The artifact kind tells the tooling which of those two outputs to produce from the same layered source.
Validate both kinds in CI
Because both outputs come from shared assets, both can break. We validate both in CI: scaffold a solution and confirm it builds and tests clean with no factory residue, and scaffold a template and confirm it can in turn generate a working solution. A nightly pipeline that exercises both kinds catches drift before it reaches a delivery, which is what lets us trust the templates as the default starting point for real work.
Wrapping up
Template-driven delivery scales only when the line between producing software and producing the tools that produce software is explicit and enforced. The solution-versus-template artifact kind draws that line with a single flag, layering makes both outputs come from one source, and CI validation keeps both honest. The result is customer code that looks hand-crafted and templates that stay genuinely reusable - the two properties a delivery org most needs at scale.
Want a delivery model that scales without chaos? Let's talk.
