Publishing a Solution

July 2, 2026 · View on GitHub

Overview

dotnet publish accepts a solution (.sln) file as input, but doing so is generally not recommended.

Why publishing a solution is problematic

CLI arguments don't flow to dependent projects correctly

When you run dotnet publish with CLI arguments on a solution, those arguments are not correctly forwarded to the individual projects inside the solution. Common examples include:

  • -r / --runtime (RuntimeIdentifier) – most library projects don't declare any RIDs, so when a RID flows down to them it changes their build behavior. Those projects will look for restore assets that were produced for that specific RID, but restore was most likely run without a RID, so the assets aren't there. Running dotnet publish --no-restore with a RID makes the situation worse: it disables the implicit restore that could otherwise recover from the missing assets.
  • -f / --framework (TargetFramework) – when a solution passes a target framework to its projects it bypasses the normal project-to-project target framework negotiation. As a result, library projects that are referenced by multiple app projects may be scheduled for build multiple times, potentially running concurrently and writing to the same intermediate output directory at the same time.

As a result, the published output may be built with the wrong runtime or framework settings, leading to subtle or hard-to-diagnose issues at runtime.

Output path conflicts with -o / --output

If you specify an output directory with -o (or --output), all projects in the solution write their outputs to the same directory. This causes two problems:

  1. Race conditions – if multiple projects are publishing simultaneously, they may try to write to the same output directory at the same time and interfere with each other.
  2. File overwriting – if multiple projects depend on different versions of a package that produces a file with the same name, the last project to publish wins and overwrites the file, potentially leaving you with an inconsistent mix of binaries.

Because of the -o concern, dotnet publish already emits a warning when -o is specified together with a solution file.

Publishing a solution only works in limited scenarios

Publishing a solution without any CLI arguments can work when:

  • All projects in the solution target the same framework and runtime.
  • No two projects produce conflicting output files.
  • You don't need to apply any publish-time customization (self-contained, single-file, trimming, etc.).

In practice these conditions are rarely all true for a non-trivial solution.

Use the following approach to achieve a reliable, repeatable publish:

  1. Build the solution to compile all projects and validate that all framework/runtime combinations work:

    dotnet build MySolution.sln
    

    This is safe because dotnet build does not produce a deployable output and the arguments flow more predictably across projects.

  2. Publish individual projects to get a deployable output for a specific runtime and framework combination:

    dotnet publish src/MyApp/MyApp.csproj -r linux-x64 -f net9.0
    

    Publishing individual projects gives you precise control over the RuntimeIdentifier, TargetFramework, self-contained mode, single-file packaging, trimming, and any other publish-time properties.

  3. Repeat for each combination you need to ship (e.g. win-x64, linux-x64, osx-arm64).

    Note that publishing each project separately for multiple RIDs will rebuild shared library projects once per RID. For advanced scenarios where you want to publish many projects for many RIDs in a single invocation you can author a traversal project that sets the appropriate properties per ProjectReference, though that approach requires more MSBuild expertise.

This approach avoids the argument-forwarding and output-path problems described above and gives you a clear mapping from source project to published artifact.

Summary

ScenarioRecommended command
Build all projects in a solutiondotnet build MySolution.sln
Publish a specific project for a specific runtimedotnet publish src/MyApp/MyApp.csproj -r <rid> -f <tfm>
Publish with custom output directorydotnet publish src/MyApp/MyApp.csproj -o out/myapp

Avoid dotnet publish MySolution.sln -r <rid>, dotnet publish MySolution.sln -f <tfm>, and dotnet publish MySolution.sln -o <dir>.