Al publicar una aplicación web de ASP.NET Core 6 con <ImplicitUsings /> de C# 10 habilitado en Azure App Service desde un perfil de publicación de Visual Studio 2022, la compilación de publicación falla debido a que faltan instrucciones de using .
C# 10 presenta la nueva función de usos implícitos , donde ciertas directivas de using se tratan como directivas de using globales basadas en el SDK. Esto se puede habilitar con la siguiente configuración csproj :
<PropertyGroup> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> Esto funciona exactamente como se esperaba con una compilación local. Por ejemplo, cuando me dirijo al SDK de Microsoft.NET.Sdk.Web , puedo eliminar el using de directivas para System , System.Collections.Generic , System.Linq , &c.
Sin embargo, al publicar en Azure App Service desde un perfil de publicación de Visual Studio 2022, el resultado de la compilación muestra errores como los siguientes:
C:\Code\MyWebApp\MyClass.cs(41,25): Error CS0246: The type or namespace name 'IEnumerable<>' could not be found (are you missing a using directive or an assembly reference?)Esto se puede ver a continuación como parte de un contexto ampliado:
Build started... 1>------ Build started: Project: MyWebApp, Configuration: Release Any CPU ------ 1>Done building project "MyWebApp.csproj". 2>------ Publish started: Project: MyWebApp, Configuration: Release Any CPU ------ Determining projects to restore... All projects are up-to-date for restore. C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\Roslyn\csc.exe /noconfig /unsafe- /checked- /nowarn:1701,1702,1701,1702,2008 /fullpaths /nostdlib+ /platform:x64 /errorreport:prompt /warn:6 /define:TRACE;RELEASE;NET;NET6_0;NETCOREAPP;NET5_0_OR_GREATER;NET6_0_OR_GREATER;NETCOREAPP1_0_OR_GREATER;NETCOREAPP1_1_OR_GREATER;NETCOREAPP2_0_OR_GREATER;NETCOREAPP2_1_OR_GREATER;NETCOREAPP2_2_OR_GREATER;NETCOREAPP3_0_OR_GREATER;NETCOREAPP3_1_OR_GREATER /errorendlocation /preferreduilang:en-US /highentropyva+ /reference: /debug+ /debug:portable /filealign:512 /optimize+ /out:obj\Release\net6.0\win-x64\MyWebApp.dll /refout:obj\Release\net6.0\win-x64\ref\MyWebApp.dll /target:exe /warnaserror- /utf8output /deterministic+ /langversion:10.0 /analyzerconfig:… /analyzer:"C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk.Web\analyzers\cs\Microsoft.AspNetCore.Analyzers.dll" /additionalfile:Areas\MyArea\Index.cshtml … /warnaserror+:NU1605 C:\Code\MyWebApp\MyClass.cs(41,25): Error CS0246: The type or namespace name 'IEnumerable<>' could not be found (are you missing a using directive or an assembly reference?) 2>Build failed. Check the Output window for more details. ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== ========== Publish: 0 succeeded, 1 failed, 0 skipped ========== Supongo que esto tiene algo que ver con el comando csc.exe generado por el perfil de publicación.
Desafortunadamente, no es inmediatamente obvio para mí cómo remediar esto dentro de mi archivo pubxml , lo cual es bastante sencillo:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <WebPublishMethod>MSDeploy</WebPublishMethod> <ResourceId>/subscriptions/77e95f68-ed69-4bfe-9bbe-0b4d3910722e/resourceGroups/ResourceGroup/providers/Microsoft.Web/sites/MyWebApp</ResourceId> <PublishProvider>AzureWebSite</PublishProvider> <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> <LastUsedPlatform>Any CPU</LastUsedPlatform> <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> <ExcludeApp_Data>False</ExcludeApp_Data> <ProjectGuid>77e95f68-ed69-4bfe-9bbe-0b4d3910722e</ProjectGuid> <MSDeployServiceURL>mywebapp.scm.azurewebsites.net:443</MSDeployServiceURL> <DeployIisAppPath>MyWebApp</DeployIisAppPath> <RemoteSitePhysicalPath /> <SkipExtraFilesOnServer>False</SkipExtraFilesOnServer> <MSDeployPublishMethod>WMSVC</MSDeployPublishMethod> <EnableMSDeployBackup>True</EnableMSDeployBackup> <UserName>$MyWebApp</UserName> <_SavePWD>True</_SavePWD> <_DestinationType>AzureWebSite</_DestinationType> <TargetFramework>net6.0</TargetFramework> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <SelfContained>false</SelfContained> <InstallAspNetCoreSiteExtension>False</InstallAspNetCoreSiteExtension> <EnableMsDeployAppOffline>True</EnableMsDeployAppOffline> </PropertyGroup> </Project> (Nota: ResourceId , ProjectGuid , &c. se han anonimizado y no se refieren a una propiedad real).
Reconociendo que esta es una característica nueva en una nueva versión de Visual Studio, esto podría ser un error. Dicho esto, ¿hay alguna propiedad pubxml que sea necesaria para habilitar la característica <ImplicitUsing /> ? ¿O se necesita algo más para habilitar esta función con los perfiles de publicación de Visual Studio?
En primer lugar, parece que se trataba de una falsa alarma. Aparentemente, olvidé terminar de reiniciar mi estación de trabajo después de instalar la versión de lanzamiento de Visual Studio 2022. Después de reiniciar, ahora puedo publicar con soporte completo para usos implícitos. ¡Vaya!
Dicho esto, esto brinda una buena oportunidad para ofrecer una idea de lo que descubrí después del hecho, lo que puede ayudar a futuros lectores con tipos de problemas similares, y ciertamente me ayudó a comprender mejor la integración entre las diversas herramientas de línea de comandos.
En particular, no parece haber ningún parámetro de línea de comandos para manejar usos implícitos integrados en ninguna de las siguientes herramientas:
dotnet.exe )csc.exe )msbuild.exe ) En su lugar, esto se maneja a través de Microsoft Build Engine ( msbuild.exe ) cuando se trabaja con un archivo de proyecto de C# ( *.csproj ), momento en el que genera el siguiente archivo intermedio en:
/{BaseIntermediateOutputPath}/{Configuration}/net6.0/{MyWebApp}.GlobalUsings.g.cspor ejemplo, por defecto:
/obj/Release/net6.0/MyWebApp.GlobalUsings.g.cs Este archivo contiene directivas de using globales que son específicas del SDK configurado:
// <auto-generated/> global using global::Microsoft.AspNetCore.Builder; global using global::Microsoft.AspNetCore.Hosting; … A su vez, este archivo se adjunta a la llamada subyacente al compilador de C# ( csc.exe ).
Nota: El SDK de .NET 6.0, es decir,
dotnet.exe, proporciona un contenedor alrededor demsbuild.execomo parte de los comandos debuildopublishy, por lo tanto, ofrece la misma funcionalidad. Además, de forma predeterminada, el SDK de .NET conservará los archivos intermedios en la carpeta/obj, mientras quemsbuild.exelos eliminará inmediatamente.
Teniendo esto en cuenta, la característica de usos implícitos no es en realidad parte de C# 10 per se , a pesar de que se anuncia como tal , sino que es más bien una herramienta integrada en Microsoft Build Engine ( msbuild.exe ). El compilador de C# 10 ( csc.exe ) admite directivas de using globales , pero no tiene conocimiento de los usos implícitos .
En última instancia, esto no es demasiado sorprendente, ya que el compilador de C# ( csc.exe ) en realidad no es consciente de los archivos de proyecto de C# ( *.csproj ), que son un artefacto de Microsoft Build Engine, con soporte de transferencia a través de el SDK de .NET.
No está claro por qué las compilaciones locales funcionaron correctamente con esto antes de un reinicio completo, mientras que fallaron las llamadas que usaban los perfiles de publicación de Visual Studio 2022. Supongo que esto tiene algo que ver con la forma en que Visual Studio ensambla los argumentos para el compilador de C# ( csc.exe ) como parte del proceso de publicación. De todos modos, es una solución fácil simplemente reiniciar la estación de trabajo después de la instalación. De lo contrario, esta publicación ayudará a desmitificar el proceso general.