Itay Barber
Itay Barber

Reputation: 3

Azure Function can't find a file/dll that it suppose to use

I have an azure webjob that used to work well. When I added an internal nuget of the company I work for and used it, I received the following error:

Could not load file or assembly 'System.Threading.Tasks.Dataflow, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

The weird thing is that both the interal nuget, and a nuget that was defualtly existed in that project before, are using the System.Threading.Tasks.Dataflow, Version=5.0.0.0

enter image description here

Upvotes: 0

Views: 2325

Answers (1)

zivkan
zivkan

Reputation: 15082

When .NET was first created, the Windows-only .NET Framework, it has a concept called "strong naming" which makes the assembly version part of the assembly identity (not just the name, but also includes public key). With the .NET Framework when A.dll has a reference to B.dll, at runtime the version of B.dll must match the version A.dll was compiled against. The way to work around that was to use a binding redirect in an app.config or web.config file.

With .NET Core, they stopped enforcing this, but they still put in a check to make sure that the assembly found on disk is a HIGHER version than what the compile time reference was.

This is relevant because you're using Microsoft.NET.Sdk.Functions version 3.0.13, which targets .NET 3.1. Therefore, I assume you're Azure Functions app is running on .NET Core 3.1. I don't know what the assembly version of System.Threading.Tasks.Dataflow that ships in the .NET 3.1 runtime is, but I'd expect it to be version 3.something.

While NuGet package versions do not have to match assembly versions, it is very often the case that the major (and sometimes minor) versions do match, especially for System.* packages/assemblies.

Putting 2+2 together, you're running on .NET Core 3.1, which has System.Threading.Tasks.Dataflow.dll version 3.something, but your something.Kafka.dll assembly is compiled against System.Threading.Tasks.Dataflow.dll version 5.something. Since the compile time reference is a higher version of the version available at runtime, the .NET assembly loader refuses to use it.

There are two actionable things now.

Firstly, you can do one of three things to fix your project. Use a newer version of Azure Functions that targets .NET 5 or higher. Alternatively, use an older version of your whatever.Kafka package that doesn't depend on BCL (base class library) assemblies that are higher version than the .NET Core 3.1 runtime provides. Finally, I'm guessing the reason the dll doesn't exist in your project's bin directory is because of this issue: https://github.com/Azure/azure-functions-host/issues/5894

Secondly, contact the package owners of this Kafka package, and inform them that they don't need to use the Dataflow NuGet package. .NET Core 1.0 had it built into the BCL, so the package is only needed for .NET Standard and .NET Framework projects. If this Kafka package does support .NET Framework or .NET Standard, then if they change their PackageReference to include Condition=" '$(TargetFrameworkIdentifier) != '.NETCoreApp' ", then the package will be used only in .NET Framework and .NET Standard, and the BCL version of the package will be used for .NET Core and .NET 5 and above. If they use any other System.* package (that ships in the runtime), they should do the same. Of course, if the package owner refuses to remove Dataflow as a package dependency, or if there are other packages that bring in Dataflow as a transitive package, then you're stuck. But by informing the Kafka package owners of this, they at least have the opportunity to improve their package.

Upvotes: 2

Related Questions