Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Dependency inconsistency in Azure.Core (netstandard2.0, affecting multiple SDK packages) #39798

Closed
avendel opened this issue Nov 7, 2023 · 7 comments
Assignees
Labels
Azure.Core Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that

Comments

@avendel
Copy link

avendel commented Nov 7, 2023

Library name and version

Azure.Core 1.35, Azure.Storage.Blobs 12.19 and 12.18

Describe the bug

When using an SDK package that transiently references Azure.Core 1.35 in a .NET Framework project, an exception is thrown when code related to System.Diagnostics.DiagnosticSource is executed. This includes creating a BlobServiceClient from Azure.Storage.Blobs.

This issue appears to stem from a mismatch between the dependency specified in the Azure.Core nuspec file and the assembly manifest.

The nuspec contains a reference to 6.0.1:

<group targetFramework=".NETStandard2.0">
    ...
    <dependency id="System.Diagnostics.DiagnosticSource" version="6.0.1" exclude="Build,Analyzers" />
    ...
</group>

However, the Azure SDK libraries built for netstandard2.0 (e.g. azure.core\1.35.0\lib\netstandard2.0\Azure.Core.dll) contain a reference to 6.0.0:

.assembly extern System.Diagnostics.DiagnosticSource
{
  .publickeytoken = (CC 7B 13 FF CD 2D DD 51 )
  .ver 6:0:0:0
}

Expected behavior

I can use Azure SDK in .NET Framework without resorting to assembly binding redirects.

Actual behavior

An exception is thrown:

System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Reproduction Steps

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <AssemblyName>azure-sdk-repro</AssemblyName>
    <TargetFramework>net48</TargetFramework>
    <AutoGenerateBindingRedirects>False</AutoGenerateBindingRedirects>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Azure.Storage.Blobs" Version="12.19.0" />
  </ItemGroup>

</Project>
internal class Program {
    static void Main() {
        var blobClient = new Azure.Storage.Blobs.BlobServiceClient(new System.Uri("https://host/"));
    }
}

The code above throw this exception when using Azure.Storage.Blobs version 12.18 and 12.19 (latest), but works for version 12.17.

Environment

  • Microsoft Visual Studio Enterprise 2022 (64-bit) - Current Version 17.7.3
  • .NET Framework 4.8
@github-actions github-actions bot added Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-triage Workflow: This issue needs the team to triage. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Storage Storage Service (Queues, Blobs, Files) labels Nov 7, 2023
@avendel
Copy link
Author

avendel commented Nov 7, 2023

For this simple reproduction, enabling automatic binding redirects would work. Things are a bit more complicated in a larger solution with multiple web projects and references to various Azure SDK packages.

@m-redding m-redding added Azure.Core needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team and removed Storage Storage Service (Queues, Blobs, Files) needs-team-triage Workflow: This issue needs the team to triage. labels Nov 7, 2023
@m-redding m-redding self-assigned this Nov 7, 2023
@m-redding
Copy link
Member

Hi @avendel apologies that you are experiencing this issue. We updated our dependency on System.Diagnostics.DiagnosticSource from 4.6.1 to 6.0.1 in Azure.Core 1.34. I don't know of any references to 6.0.0 in any of our packages, but I will look into this further to try and see what could be causing it. In the meantime would you mind providing a bit more clarification on your repro? I created a console app with automatic binding redirects enabled and used the .csproj and program.cs file that you linked above. I wasn't able to reproduce the error you are seeing, is there anything else needed in the configuration to reproduce this exception?

@avendel
Copy link
Author

avendel commented Nov 8, 2023

@m-redding Thanks for looking into this.

With automatic binding redirects enabled, the problem isn't reproducible. If you use the exact csproj from my minimal reproduction (with automatic redirects disabled), do you get the same exception as me? I have been able to reproduce the issue on a Windows 11 dev workstation and on Windows Server 2022 Data Center Edition, both when built using Visual Studio 2022 and using a dotnet 8 preview SDK.

I would expect having to resort to binding redirects with multiple dependencies of different versions. However, in this case I'm only referencing the Azure.Storage.Blobs package. I don't expect binding redirects would be necessary in that scenario. For web apps, automatic redirects aren't as automatic either.

I agree that it looks like your explicit dependencies seem to be on 6.0.1, but the actual references as specified in the compiled dlls are for 6.0.0. I used both ildasm and dotPeek. See screenshot from dotPeek below:

image

Maybe this is related to how netstandard references are found (https://learn.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblies)? On my computer, they seem to use dlls from C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.x\ref\net6.0, where I find only System.Diagnostics.DiagnosticSource 6.0.0.

I don't rule out that there is something in my environment causing this, but since I see other similar issues in this repository (#39632, #38857), I thought it would be worth bringing my findings to your attention.

@m-redding
Copy link
Member

Ok after disabling automatic redirects I am seeing the same exception as you. I'm also using Visual Studio 2022 and the latest dotnet 8 preview to run.
My initial thought is the same as yours, that there is something unexpected happening when the netstandard references are being found. I'll look into this more and keep you updated with what I find. I'm going to mark the other issue as a duplicate and keep updates in this thread.

@brah2008
Copy link

Subject: [BUG] Dependency Inconsistency in Azure.Core (Azure.Storage.Blobs 12.19 and 12.18) affecting .NET Framework Projects

Dear Azure.Core and Azure.Storage.Blobs Teams,

I hope this message finds you well. I am reaching out to report a bug related to a dependency inconsistency in Azure.Core, specifically affecting versions 1.35.0, Azure.Storage.Blobs 12.19.0, and 12.18.0. This issue arises when using these versions in a .NET Framework project, causing an exception related to System.Diagnostics.DiagnosticSource.

Bug Description:
When using Azure.Storage.Blobs versions 12.19.0 and 12.18.0 in a .NET Framework project, a System.IO.FileLoadException is thrown, indicating a mismatch between the specified dependency version in the Azure.Core nuspec file and the assembly manifest.

Reproduction Steps:

  1. Create a .NET Framework project targeting version 4.8.

  2. Add a reference to Azure.Storage.Blobs version 12.19.0 or 12.18.0.

  3. Attempt to execute code involving Azure.Storage.Blobs, such as creating a BlobServiceClient.

  4. Observe the thrown exception related to System.Diagnostics.DiagnosticSource.

Expected behavior:
The Azure SDK can be used in a .NET Framework project without requiring assembly binding redirects, and the specified dependency versions match in the Azure.Core nuspec file and the assembly manifest.

Actual behavior:
An exception is thrown, indicating a mismatch between the Azure.Core nuspec file and the assembly manifest for System.Diagnostics.DiagnosticSource.

Environment:

Visual Studio: Enterprise 2022 (64-bit), Current Version 17.7.3
.NET Framework: 4.8

Additional Information:

Azure.Core Version: 1.35.0
Azure.Storage.Blobs Versions: 12.19.0, 12.18.0
Proposed Solution:
Align the dependency version in the Azure.Core nuspec file for System.Diagnostics.DiagnosticSource with the version referenced in the Azure SDK libraries built for netstandard2.0 (e.g., azure.core\1.35.0\lib\netstandard2.0\Azure.Core.dll).

I appreciate your attention to this matter and look forward to a resolution. If you require further details or clarification, please feel free to reach out.

Best regards,

@m-redding
Copy link
Member

m-redding commented Nov 14, 2023

Hello, apologies again for the difficulties here. I've been investigating this issue and have found some information so far that I wanted to add. I'm going to consult with some other people who have more .NET context in order to get a better idea of how we should move forward.

Binding redirects are specific to .NET Framework. .NET core uses deps.json to resolve dependencies. If you look at the assembly manifest, System.Diagnostics.DiagnosticSource is loaded as 6.0.0 in all .NET versions (not just .NET Framework 4.8). If you looked at the console app's net6.0 deps.json file, it contains the following:

"System.Diagnostics.DiagnosticSource/6.0.1": {
  "dependencies": {
    "System.Runtime.CompilerServices.Unsafe": "6.0.0"
  },
  "runtime": {
    "lib/net6.0/System.Diagnostics.DiagnosticSource.dll": {
      "assemblyVersion": "6.0.0.0",
      "fileVersion": "6.0.1523.11507"
    }
  }
},

Which is similar to what a binding redirect would do for .NET framework.

It seems that the guidelines for avoiding this problem from the .NET team in general is to use binding redirects. The default behavior of a .NET framework desktop app in visual studio uses automatic binding redirection. In addition, I was able to find the following guidance from various sources in the runtime repository:

"The very likely reason why it is not working in your scenario, is because you are likely not using binding redirects in your .NET Framework project. In order to use .NET Standard assets in .NET Framework projects, binding redirects are almost always a requirement, and that's the case here." dotnet/runtime#77887 (comment)

"...while relying on customers to use bindingRedirects - which we view as a necessity, regardless, when consuming NuGet packages on .NETFramework." dotnet/runtime#77887 (comment)

"As best I can tell this is by design behavior because the assembly redirections in the app.config file were necessary to retarget the 4.x reference to the 6.x assembly.... eliminating redirects seems like it might block you from using many NuGet packages. " dotnet/runtime#93421

I'm not entirely certain why this change would be breaking only for Azure.Core 1.34 and beyond. I tested this exact same app with Azure.Storage.Blobs 12.17.0 and can run with no issues. Also, using dotPeek to look at the nupkg of Azure.Core 1.33 shows that the nuspec is System.Diagnostics.DiagnosticSource >= 4.6.0, while the assembly manifest is System.Diagnostics.DiagnosticSource 4.0.4.0. One of the issues I linked below also seems to imply that the framework is looking for 4.0.4.0, which means that they were able to access the version somehow. This leads me to wonder if something else could be going on here.

With all that being said, I do not think this is desirable behavior. Especially given that it is impacting so many people, and (as you mentioned) automatic redirects are not always easy to enable. I will continue to investigate and see how we can address the issue.

Duplicates: dotnet/runtime#93177 Visual Studio Community Issue
Similar: Visual Studio Community Issue dotnet/runtime#61445 (comment)

@m-redding
Copy link
Member

After talking this over with more people on our team, the expectation is that binding redirects are required in order to use .NET standard packages in .NET framework projects.
It seems this particular reference had worked previously by chance. Most likely there was a reference somewhere already loaded in that allowed the previous version of System.Diagnostics.DiagnosticSource to work correctly in .NET framework projects.
This outcome isn't ideal, but the version upgrade was overdue, and necessary in order to support new features and initiatives in our SDKs (such as AOT compilation).

@m-redding m-redding closed this as not planned Won't fix, can't repro, duplicate, stale Feb 22, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Azure.Core Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that
Projects
None yet
Development

No branches or pull requests

3 participants