extensions icon indicating copy to clipboard operation
extensions copied to clipboard

The logging source generator emits `CS0757` errors when referencing `Microsoft.Extensions.Resilience`

Open ZzZombo opened this issue 1 year ago • 18 comments

Description

See also #4286, #4565.

Right after I added this package reference to my SDK-style project targeting net8.0-windows for my WPF program I started to get these errors.

Reproduction Steps

A new WPF application targeting .NET 8, using the following packages:

 		<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
		<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
		<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
		<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
		<PackageReference Include="Microsoft.Extensions.Resilience" Version="8.2.0" />

Expected behavior

No error.

Actual behavior

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS0757	A partial method may not have multiple implementing declarations	Program	G:\home\dev\csharp\temp\src\Microsoft.Extensions.Logging.Generators\Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator\LoggerMessage.g.cs	13	Active

Regression?

See also #4286, #4565.

Known Workarounds

None barring not using the package.

Configuration

.NET SDK: Version: 8.0.200 Commit: 438cab6a9d Workload version: 8.0.200-manifests.e575128c

Runtime Environment: OS Name: Windows OS Version: 10.0.19045 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.200\

.NET workloads installed: [maui-windows] Installation Source: VS 17.9.34616.47 Manifest Version: 8.0.6/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.6\WorkloadManifest.json Install Type: FileBased

[android] Installation Source: VS 17.9.34616.47 Manifest Version: 34.0.52/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.52\WorkloadManifest.json Install Type: FileBased

[ios] Installation Source: VS 17.9.34616.47 Manifest Version: 17.2.8004/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.2.8004\WorkloadManifest.json Install Type: FileBased

[maccatalyst] Installation Source: VS 17.9.34616.47 Manifest Version: 17.2.8004/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.2.8004\WorkloadManifest.json Install Type: FileBased

Host: Version: 8.0.2 Architecture: x64 Commit: 1381d5ebd2

.NET SDKs installed: 8.0.200 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.27 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Other information

No response

ZzZombo avatar Feb 26 '24 10:02 ZzZombo

Could somebody at least point to a workaround? This is a blocking issue for us.

ZzZombo avatar Feb 28 '24 11:02 ZzZombo

There's a conflict of packages similar to the issues that you've already found.

AFAIK, Microsoft.Extensions.Telemetry.Abstractions carries a source generator that replaces a source generator from Microsoft.Extensions.Logging.Generators, and it's doing so via <DisableMicrosoftExtensionsLoggingSourceGenerator>true</DisableMicrosoftExtensionsLoggingSourceGenerator> MSBuild property. https://github.com/dotnet/extensions/blob/88d79f71e9af747fceb087ea9261b697d29ae71d/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net6.0/Microsoft.Extensions.Telemetry.Abstractions.props#L2-L5 https://github.com/dotnet/extensions/blob/88d79f71e9af747fceb087ea9261b697d29ae71d/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net6.0/Microsoft.Extensions.Telemetry.Abstractions.targets#L2-L15

Can you verify Microsoft.Extensions.Telemetry.Abstractions is being referenced by your project? And _Microsoft_Extensions_Logging_AbstractionsRemoveAnalyzers is being executed?

RussKie avatar Feb 29 '24 09:02 RussKie

Can you verify Microsoft.Extensions.Telemetry.Abstractions is being referenced by your project?

Directly or transitively?

And _Microsoft_Extensions_Logging_AbstractionsRemoveAnalyzers is being executed?

Can you explain to me how to do this part?

ZzZombo avatar Feb 29 '24 10:02 ZzZombo

The easiest way to do both of those is to capture and inspect a binary log. Please see https://msbuildlog.com/ for more information.

Perhaps, try referencing Microsoft.Extensions.Telemetry.Abstractions directly?

RussKie avatar Mar 01 '24 00:03 RussKie

Adding the package directly had no effect. For other answers please see the screenshot. image

ZzZombo avatar Mar 01 '24 01:03 ZzZombo

You mentioned that your project is targeting net8.0-windows but the screenshot is showing you're consuming net9 packages... Could you please clarify why?

RussKie avatar Mar 01 '24 05:03 RussKie

You mentioned that your project is targeting net8.0-windows but the screenshot is showing you're consuming net9 packages... Could you please clarify why?

It was to see if doing so fixes this issue. Previously I targeted .NET 8.

ZzZombo avatar Mar 01 '24 07:03 ZzZombo

Hello @ZzZombo, I was just trying to reproduce the issue but had no luck: image

Are there any specific steps I also need to take? I'm using .NET SDK 8.0.200 as you mentioned in the post and also tried to repro with the .NET CLI, but it still builds the project just fine: image

xakep139 avatar Mar 07 '24 17:03 xakep139

@xakep139: this is stripped down project file that still shows the problem for us:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup Label="General build">
		<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
		<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
		<TargetFramework>net8.0-windows</TargetFramework>
		<PlatformTarget>AnyCPU</PlatformTarget>
		<OutputType>WinExe</OutputType>
		<ProjectGuid>{<snip/>}</ProjectGuid>
		<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
		<AssemblyName>Program</AssemblyName>
		<FileAlignment>512</FileAlignment>
		<WarningLevel>4</WarningLevel>
		<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
		<Deterministic>true</Deterministic>
		<UseWPF>true</UseWPF>
		<UseWindowsForms>False</UseWindowsForms>
		<StartupObject>Company.App</StartupObject>
		<NeutralLanguage>en-US</NeutralLanguage>
		<UserSecretsId><snip/></UserSecretsId>
		<MSBuildCopyContentTransitively>true</MSBuildCopyContentTransitively>
		<EnableConfigurationBindingGenerator>false</EnableConfigurationBindingGenerator>
		<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
	</PropertyGroup>
	<PropertyGroup Condition="'$(Platform)' == 'AnyCPU' ">
		<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
		<ErrorReport>prompt</ErrorReport>
		<WarningLevel>4</WarningLevel>
	</PropertyGroup>
	<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
		<DebugSymbols>true</DebugSymbols>
		<DebugType>full</DebugType>
		<Optimize>false</Optimize>
		<DefineConstants>DEBUG;$(DefineConstants)</DefineConstants>
	</PropertyGroup>
	<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
		<DebugType>pdbonly</DebugType>
		<Optimize>true</Optimize>
	</PropertyGroup>
	<PropertyGroup Label="General code">
		<LangVersion>12</LangVersion>
		<RootNamespace>Company</RootNamespace>
		<Nullable>enable</Nullable>
		<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
	</PropertyGroup>
	<ItemGroup Label="Generic Host/DI/Services">
		<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.2" />
		<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0-preview.1.24080.9" />
		<PackageReference Include="Microsoft.Extensions.Resilience" Version="9.0.0-preview.1.24108.1" />
		<PackageReference Include="NReco.Logging.File" Version="1.2.0" />
	</ItemGroup>
</Project>

ZzZombo avatar Mar 12 '24 11:03 ZzZombo

Okay, you missed the usage of [LoggerMessage] in your reproduction steps. Here's the minimal repro:

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<TargetFramework>net8.0-windows</TargetFramework>
		<OutputType>WinExe</OutputType>
		<UseWPF>true</UseWPF>
	</PropertyGroup>
	<ItemGroup>
		<PackageReference Include="Microsoft.Extensions.Resilience" Version="8.0.0" />
	</ItemGroup>
</Project>

And Log.cs:

using Microsoft.Extensions.Logging;

internal static partial class Log
{
	[LoggerMessage(Level = LogLevel.Information, Message = "Message")]
	public static partial void LogInformation(ILogger logger);
}

xakep139 avatar Mar 12 '24 15:03 xakep139

Even if I replace Microsoft.Extensions.Resilience reference with Microsoft.Extensions.Telemetry.Abstractions package, it still emits the same error

xakep139 avatar Mar 12 '24 15:03 xakep139

I've run some local tests and wonder why we we didn't implement the target this way:

--- a/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net8.0/Microsoft.Extensions.Telemetry.Abstractions.targets
+++ b/src/Libraries/Microsoft.Extensions.Telemetry.Abstractions/buildTransitive/net8.0/Microsoft.Extensions.Telemetry.Abstractions.targets
@@ -2,10 +2,10 @@
   <!-- This package should replace the Microsoft.Extensions.Logging.Abstractions source generator. -->
   <Target Name="_Microsoft_Extensions_Logging_AbstractionsRemoveAnalyzers" 
           Condition="'$(DisableMicrosoftExtensionsLoggingSourceGenerator)' == 'true'"
-          AfterTargets="ResolveReferences">
+          AfterTargets="RemoveDuplicateAnalyzers">
     <ItemGroup>
-      <_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.AssemblyName)' == 'Microsoft.Extensions.Logging.Generators' Or
-                                                                                           '%(Analyzer.NuGetPackageId)' == 'Microsoft.Extensions.Logging.Abstractions'" />
+      <_Microsoft_Extensions_Logging_AbstractionsAnalyzer Include="@(Analyzer)" Condition="'%(Analyzer.Filename)' == 'Microsoft.Extensions.Logging.Generators' Or
+                                                                                           '%(Analyzer.Filename)' == 'Microsoft.Extensions.Logging.Abstractions'" />
     </ItemGroup>
 
     <!-- Remove Microsoft.Extensions.Logging.Abstractions Analyzer -->

This way I was able to build a WPF sample without any additional changes.

@joperezr any thoughts?

RussKie avatar Mar 19 '24 00:03 RussKie

@joperezr gentle nudge

RussKie avatar Mar 29 '24 02:03 RussKie

@RussKie, will your target also work on non-WPF projects?

xakep139 avatar Apr 10 '24 11:04 xakep139

will your target also work on non-WPF projects?

It should work universally. More tests will be required to confirm. I'm still waiting on @joperezr (we've been busy with other high prio work), but we've aiming to have a resolution for this issue for the .5 release.

RussKie avatar Apr 10 '24 22:04 RussKie

It should work universally.

@RussKie my concern was that RemoveDuplicateAnalyzers target might exist for WPF apps only

xakep139 avatar May 15 '24 14:05 xakep139

It should work universally.

my concern was that RemoveDuplicateAnalyzers target might exist for WPF apps only

Yes, you're right. That target is part of the Windows Desktop SDK: image

RussKie avatar May 17 '24 02:05 RussKie

This should work:

  <Target Name="_Microsoft_Extensions_Logging_AbstractionsRemoveAnalyzers" 
          Condition="'$(DisableMicrosoftExtensionsLoggingSourceGenerator)' == 'true'"
-         AfterTargets="ResolveReferences">
+         BeforeTargets="CoreCompile">

Tested for a console app, webapi app and for a WPF apps.

RussKie avatar May 17 '24 02:05 RussKie