Публикация проекта .NET 6 с неявным использованием C# 10 через Visual Studio 2022

При публикации веб-приложения ASP.NET Core 6 с C# 10 <ImplicitUsings /> включен в службу приложений Azure из профиля публикации Visual Studio 2022, сборка публикации завершается ошибкой из-за отсутствия операторов.

Фон

В C# 10 представлена ​​новая функция неявного использования , в которой определенные директивы рассматриваются как глобальные директивы на основе SDK. Это можно включить с помощью следующих csproj конфигурация:

      <PropertyGroup>
    <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

Это работает точно так, как ожидалось, с локальной сборкой. Например, при нацеливании на Microsoft.NET.Sdk.Web SDK, я могу удалить using директивы для System, System.Collections.Generic, System.Linqи т. д.

Ошибка публикации

Однако при публикации в службу приложений Azure из профиля публикации Visual Studio 2022 в выходных данных сборки отображаются следующие ошибки:

      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?)

Это можно увидеть ниже как часть расширенного контекста:

      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 ==========

Я предполагаю, что это как-то связано с csc.exe команда, созданная профилем публикации.

Профиль публикации

К сожалению, мне не сразу понятно, как исправить это в моем файле, что довольно просто:

      <?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>

(Примечание: ResourceId, ProjectGuidи т. д. анонимизированы и не относятся к реальной собственности.)

Вопрос

Признавая, что это новая функция в новой версии Visual Studio, это может быть ошибкой. Тем не менее, есть ли pubxml свойства, необходимые для включения <ImplicitUsing />характерная черта? Или есть что-то еще, что необходимо для включения этой функции с профилями публикации Visual Studio?

1 ответ

Во-первых, похоже, что это была ложная тревога. Очевидно, я забыл завершить перезагрузку своей рабочей станции после установки окончательной версии Visual Studio 2022. После перезапуска я теперь могу публиковать с полной поддержкой неявного использования. Упс.

Тем не менее, это дает хорошую возможность дать некоторое представление о том, что я обнаружил постфактум, что может помочь будущим читателям с подобными проблемами и, безусловно, помогло мне лучше понять интеграцию между различными инструментами командной строки.

Аргументы командной строки

Примечательно, что нет никаких параметров командной строки для обработки неявного использования, встроенного в любой из следующих инструментов:

  • Пакет SDK для .NET 6.0 ()
  • Визуальный компилятор C# ()
  • Механизм сборки Майкрософт ()

Поддержка сборки Майкрософт

Вместо этого это обрабатывается с помощью Microsoft Build Engine () при работе с файлом проекта C# (), после чего он генерирует следующий промежуточный файл по адресу:

      /{BaseIntermediateOutputPath}/{Configuration}/net6.0/{MyWebApp}.GlobalUsings.g.cs

например, по умолчанию:

      /obj/Release/net6.0/MyWebApp.GlobalUsings.g.cs

Этот файл содержит глобальные директивы, относящиеся к настроенному SDK:

      // <auto-generated/>
global using global::Microsoft.AspNetCore.Builder;
global using global::Microsoft.AspNetCore.Hosting;
…

В свою очередь, этот файл добавляется к базовому вызову компилятора C#().

Примечание. Пакет SDK для .NET 6.0, т. е. dotnet.exe— обеспечивает обертку как часть buildили publishкоманд и, таким образом, предлагает ту же функциональность. Кроме того, по умолчанию .NET SDK сохраняет промежуточные файлы в /objпапку, тогда как сразу удаляет их.

Поддержка С# 10

Учитывая это, функция неявного использования на самом деле не является частью C# 10 как таковой , несмотря на то, что рекламируется как таковая , а представляет собой небольшой инструментарий, встроенный в Microsoft Build Engine ( msbuild.exe). Компилятор C# 10 ( поддерживает глобальные)usingдирективы , но не знает о неявном использовании.

В конечном счете, это не так уж удивительно, поскольку компилятор C# () на самом деле не знает о файлах проекта C# ( *.csproj) — это артефакт Microsoft Build Engine с сквозной поддержкой через .NET SDK.

Вывод

Непонятно, почему локальные сборки успешно работали с этим до полной перезагрузки, а вызовы с использованием профилей публикации Visual Studio 2022 завершились неудачно. Я предполагаю, что это как-то связано с тем, как Visual Studio собирает аргументы для компилятора C# ( csc.exe) как часть процесса публикации. Несмотря на это, проще всего просто перезагрузить рабочую станцию ​​после установки. В противном случае, этот пост, мы надеемся, поможет демистифицировать весь процесс.

Другие вопросы по тегам