Aller au contenu

Le format du fichier solution .slnx

Présentation

Début 2025, depuis la version 90.200 du SDK, nous avons vu apparaître un nouveau format pour les fichiers solutions : le format SLNX. Il est privilégié dans Visual Studio 2026, car c’est le format par défaut dans les projets ciblant .NET 10.

Pourquoi ce nouveau format de fichier Solution (SLNX) ?

Le format historique .sln présente plusieurs limites. Sa structure textuelle est difficile à lire et à maintenir, particulièrement dans les solutions comportant de nombreux projets. De plus, les conflits de fusion dans Git peuvent être délicats à résoudre lorsque plusieurs développeurs modifient simultanément la solution.

Ce format SLNX repose sur XML, une structure hiérarchique plus lisible et plus concise. L'ajout d'un projet devient extrêmement simple : un unique élément <Project> suffit (au lieu de plusieurs lignes dans l’ancien format), facilitant la compréhension du fichier et réduit le risque de conflits lors des opérations de fusion dans Git. Voici un exemple :

<Solution>
  <Project Path="Api\WebApi.csproj" />
  <Project Path="Api\Shared.csproj" />
</Solution>

Migrer du format .sln au format .slnx

Voici la commande PowerShell à exécuter une fois positionné dans le répertoire contenant le fichier SLN :

dotnet sln migrate

Cette commande lit le fichier .sln existant et génère un nouveau fichier .slnx équivalent, au format XML. Le fichier .sln d’origine est conservé, ce qui permet de revenir en arrière si nécessaire. Nous pouvons le conserver, après avoir adapté les éventuels scripts de build, pipelines CI/CD, qui référencent encore l’ancien fichier .sln.

Exemple de migration

Voici un exemple de fichier .sln avec 3 projets :

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.3.11520.95
MinimumVisualStudioVersion = 10.0.40219.1

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonApp.Web", "src\MonApp.Web\MonApp.Web.csproj", "{A7AA7D4D-7655-4011-9BE6-82A44E5358AC}"
EndProject

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonApp.Application", "src\MonApp.Application\MonApp.Application.csproj", "{77B1C593-CCC5-4349-8044-5D089AAA929F}"
EndProject

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonApp.Domain", "src\MonApp.Domain\MonApp.Domain.csproj", "{E0B8B8F4-5F18-47CD-9D9B-68BC7520ED87}"
EndProject

Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection

    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {A7AA7D4D-7655-4011-9BE6-82A44E5358AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {A7AA7D4D-7655-4011-9BE6-82A44E5358AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {A7AA7D4D-7655-4011-9BE6-82A44E5358AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {A7AA7D4D-7655-4011-9BE6-82A44E5358AC}.Release|Any CPU.Build.0 = Release|Any CPU

        {77B1C593-CCC5-4349-8044-5D089AAA929F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {77B1C593-CCC5-4349-8044-5D089AAA929F}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {77B1C593-CCC5-4349-8044-5D089AAA929F}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {77B1C593-CCC5-4349-8044-5D089AAA929F}.Release|Any CPU.Build.0 = Release|Any CPU

        {E0B8B8F4-5F18-47CD-9D9B-68BC7520ED87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {E0B8B8F4-5F18-47CD-9D9B-68BC7520ED87}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {E0B8B8F4-5F18-47CD-9D9B-68BC7520ED87}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {E0B8B8F4-5F18-47CD-9D9B-68BC7520ED87}.Release|Any CPU.Build.0 = Release|Any CPU
    EndGlobalSection
EndGlobal

Une fois migré, nous obtenons le résultat suivant :

<Solution>
  <Project Path="src/MonApp.Web/MonApp.Web.csproj" />
  <Project Path="src/MonApp.Application/MonApp.Application.csproj" />
  <Project Path="src/MonApp.Domain/MonApp.Domain.csproj" />
</Solution>

Avec le fichier .slnx, la solution est essentiellement une description de la composition de l’application. Les paramètres de génération, comme Debug ou Release, sont définis dans les fichiers projets .csproj, ou par des fichiers communs tels que Directory.Build.props.