Nuget package references cause "Could not load file or assembly" ? - c#

There is a recent principle on Nuget package parsing. For details, see how NuGet parses package dependencies. A Microsoft diagram is used to explain:
This time you will choose the most recent package, which is the 2.0 version.
no problem.
One problem I encountered today is that one of my Nuget packages (called Package A current version 1.2.3) originally only supports the version of netstandard 2.0, which is defined in the csproj file.
<TargetFramework>netstandard2.0</TargetFramework>
I have another product, the ECS Nuget package (called Package B version 1.0.0), and Package B needs to reference Package A.
The relationship route is [Package B 1.0.0] -> [Package A 1.2.3]
At this time, the two packages in the program can be used normally.
Later, due to the support of the .net framework, I modified the original package A nuget package and changed it to the following.
<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
Package A package generation version is 1.3.2. At this time, I refer to the above two packages and find that the compilation is ok, but I am getting an error at runtime.
I can solve the above problem by upgrading Package B, but why is this error?
Is it because of the use of TargetFrameworks?
I also hope that the big men will give pointers.

When I compare the *.deps.json file, I found something helpful. Here is the first scenario get the following json file:
"aliyun-net-sdk-core/1.3.2": {
"dependencies": {
"Serilog": "2.5.0",
"Serilog.Exceptions": "4.0.0",
"Serilog.Sinks.File": "4.0.0"
},
"runtime": {
"lib/netstandard2.0/aliyun-net-sdk-core.dll": {
"assemblyVersion": "0.0.0.0",
"fileVersion": "0.0.0.0"
}
}
}
Because of the reference to version 1.3.2, however, the CLR can't find the DLL with Version 1.3.2 when loading the assembly, there is only assembly version 0.0.0.0, so the CLR looks for the 1.2.3 version referenced by the original project, but it is not found, so it reports an error.
Clearly understood.
After I make up the miss assembly version of the project, I got the
right result.

Related

Nuget PackageReference fails to manage multiple versions of sub dependency

Context
I have an application which has a dependency graph which looks like...
My Application
Dependency1 v1.0
Microsoft.Extensions.Configuration.Abstractions v5.0
Dependency2 v3.1.22
Microsoft.Extensions.Configuration v3.1.22
Microsoft.Extensions.Configuration.Abstractions v3.1.22
Aka, two different dependencies rely on Microsoft.Extensions.Configuration.Abstractions. All dependencies are minimum versions, and are indicated as allowing higher versions. Seemingly, both should accept v5.0.
Nuget correctly picks version 5.0 as the version of the dll it put out in the bin folder. But, at runtime, when My Application tries to use Dependency2, it throws an exception:
Could not load file or assembly 'Microsoft.Extensions.Configuration.Abstractions, Version=3.1.22.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
What I've tried
Installing Microsoft.Extensions.Configuration.Abstractions v5.0 explicitly
This made the dependency graph look like:
My Application
Dependency1 v1.0
Microsoft.Extensions.Configuration.Abstractions v5.0
Dependency2 v3.1.22
Microsoft.Extensions.Configuration v3.1.22
Microsoft.Extensions.Configuration.Abstractions v3.1.22
Microsoft.Extensions.Configuration.Abstractions v5.0
and otherwise changed nothing. Still get the exception.
Downgrading Dependency1 to use an older version
I had a similar issue with another dependency, and resolved that by lowering the version of the dependencies until their subdependencies' versions matched.
However, Dependency1 does not have an older version that relies on Microsoft.Extensions.Configuration.Abstractions 3.1.22, so I could not do the same on this one.
Nor can I upgrade Dependendency2 to a newer version that relies on Microsoft.Extensions.Configuration.Abstractions 5.0, because then it breaks the other one I already fixed.
Setting the DependencyVersion behavior on Dependency2 to Highest instead of Lowest
The answers on this question suggested setting the DependencyVersion behavior on Dependency2 to Highest.
I did not have the UI option described in that question, so instead I ran this command in the PackageManagerConsole
Install-Package Dependency2 -Version 3.1.22 -DependencyVersion Highest
This seemingly made no difference. It still throws the exception, but also I'm not seeing any feedback that suggests the DependencyVersion was changed for that particular dependency. I'm not sure if I missed the place to check that, or if the DependencyVersion is just not available for PackageReference projects, but I'm not sure what else to try.
I am at the limit of things I can find to try. Is there a way to tell .NET which version of Microsoft.Extensions.Configuration.Abstractions to use explicitly, for all dependencies? Or something similar to Package.config's binding redirects that let you roll old versions of packages into new versions, but for PackageReference?

In my .Net Standard Library project, System.Configuration.ConfigurationManager does not seem to work

In my .Net Standard Library Project,
System.Configuration.ConfigurationManager does not seem to work.
Even the method Does not get called, which contains the Statement
object o = ConfigurationManager.GetSection(_strSectionName);
I have Installed the Nuget package
System.Configuration.ConfigurationManager version 4.6.0
But if I right click on ConfigurationManager in this statement,
object o = ConfigurationManager.GetSection(_strSectionName);
It shows me the metadata of version 4.0.2.0, namely
Assembly System.Configuration.ConfigurationManager, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
where I think the version it should go to is 4.6.0.
Maybe that is causing the problem.
The assembly version is correct, it should be 4.0.2.0, this is separate from the package version (here 4.6.0).
This is not the cause of your problem. The next thing to look at is the exception, or the incorrect behaviour.

Error when referring .Net Standard project in Xamarin Android Project

I'm getting this error when I add a reference to the .Net Standard project in the Andoid Project.
Severity Code Description Project File Line Suppression State
Error Can not resolve reference: System.Threading.Tasks.Extensions,
referenced by DotNetty.Transport. Please add a NuGet package or
assembly reference for System.Threading.Tasks.Extensions, or remove
the reference to DotNetty.Transport. VFMApp.Droid
I tried:
Neither NuGet packages (System.Threading.Tasks.Extensions / DotNetty.Transport), clean solution, compiled project successfully, reference project, compile: ERROR
NuGet package for DotNetty.Transport, clean solution, compiled project successfully, reference project, compile: ERROR
NuGet package for System.Threading.Tasks.Extensions, clean solution, compile project successfully, reference project, compile: ERROR
Both NuGet packages (System.Threading.Tasks.Extensions / DotNetty.Transport), clean solution, compile project successfully, reference project, compile: ERROR
Packages in .Net Standard project:
Acr.UserDialogs 7.0.1
Humanizer 2.5.16
Microsoft.Azure.Devices.Client 1.18.1
Microsoft.Azure.Mobile.Client 4.1.1
Microsoft.Azure.Mobile.Client.SQLiteStore 4.1.1
NETStandard.Library 2.0.3
Plugin.Share 7.1.1
Refractored.MvvmHelpers 1.4.1-beta
Xam.Plugin.Connectivity 4.0.0.190-beta
Xam.Plugin.DeviceInfo 4.1.0-beta
Xam.Plugin.Geolocator 4.5.4-beta
Xam.Plugin.Media 4.1.1-beta
Xam.Plugins.Settings 4.0.0.10-beta
Packages in Android project:
Xamarin.Android.Support.Compat 28.0.0
Xamarin.Android.Support.Design 28.0.0
Xamarin.GooglePlayServices.Maps 60.1142.1
I was able to get the same error as you when I referenced DotNetty.Transport from a Xamarin.Android project compiling/targeting against API Level 28. It seems to be an issue with System.Threading.Tasks.Extensions v4.5.1 that DotNetty.Transport is referencing. Here is a link to a similar problem from another project:
https://github.com/dotnet/reactive/issues/803
To sum up the issue, it looks like that Systems.Threading.Tasks.Extensions v4.5.1 has an empty profile for MonoAndroid10. Because the profile is empty, it can not resolve the System.Threading.Tasks.Extensions.dll file, thus the error.
To fix this, you have to update your android *.csproj file and redirect the reference to use the System.Threading.Tasks.Extensions.dll that is defined in the netstandard2.0 profile.
I performed the following steps:
Add the System.Threading.Tasks.Extensions v4.5.1 nuget package to your Xamarin.Android project.
Add the System.Runtime.CompilerServices.Unsafe v4.5.2 nuget package to your Xamarin.Android project
Close Visual Studio.
Open your Xamarin.Android *.csproj file with a Text Editor.
Add another <ItemGroup> to tell your project to use the .netstandard2.0 profile instead of the MonoAndroid10 profile
<ItemGroup>
<Reference Include="System.Threading.Tasks.Extensions">
<HintPath>$(UserProfile)\.nuget\packages\system.threading.tasks.extensions\4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
</ItemGroup>
So it should look something like this:
Save the file and reload your project in visual studio. After I did that I was able to compile successfully.

Program is referring to a different version of Newtonsoft.JSON although a different version is loaded

I was working on a project to Self host a Web API project.
There are two packages 1) Microsoft.AspNet.WebAPi.SelfHost
2) Microsoft.AspNet.WebApi. I had run into a problem where two different versions of NewtonSoft.Json had been installed by the above packages and it showed a compile-time warning as well as a run time exception. If I install Microsoft.AspNet.WebAPi.SelfHost before Microsoft.AspNet.WebApi then Newtonsoft.Json version 6.0.0.0. is installed by the former and the version 11.0.0.0 by the later which gives the error. but if I install Microsoft.AspNet.WebApi, then version 11.0.0.0 is installed and Microsoft.AspNet.WebAPi.SelfHost doesn't install Newtonsoft.Json but I still get the following error
"Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its >dependencies. The located assembly's manifest definition >does not match the assembly reference. (Exception from >HRESULT: 0x80131040)/nSystem.IO.FileLoadException"
although the following is the entry in my web.config reference
"culture="neutral" publicKeyToken="30ad4fe6b2a6aeed"
bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />"
I am really not getting why it is referring to version 6.0.0.0 when a newer version is installed. And if I need both the versions how do I refer to each without causing compiler issues.
Edit: Another thing to mention here is that it errors only after publishing the file but if I run it in release mode, no issue is occurring.
I have tried this after creating a new folder from scratch.
Edit: I have also tried checking the GAC. Newtonsoft.JSON is not available in the GAC. Can anyone tell how to check the manifest/config file of a third-party package like the Microsoft.AspNet.WebAPi.SelfHost
Edit: I also checked the solutions from the linked thread, but it didn't help.
Edit: I just now edited Microsoft.Owin from version 2.0.2 to version 4, but strangely after publishing and running it is still referring to version 2. I checked web.config and package.config, they have correct assembly redirects as well as correct package. So i guess there is some other place where it is not getting updated. Anyone can help me on this?

Can't use System.Configuration.Configuration manager in a .NET Standard2.0 library on .NET FX4.6

I have an assembly created in NetStandard2.0. It reads AppSettings using System.Configuration.ConfigurationManager. I have installed nuget package of System.Configuration.ConfigurationManager with version 4.4.X which is suitable for NetStandard2.0.
When I refer this assembly in console app (.Net Core) it is reading AppSettings properly, but when I refer this assembly in old .NetFramework(4.6.X) console app it is not working and throwing an exception.
Please see the code below.
Assembly 1: NetStandard 2.0
Nuget: System.Configuration.ConfigurationManager 4.4.0
using System.Configuration;
namespace Bootstrapper.Lib
{
public class Bootstrapper
{
public Bootstrapper()
{
}
public void LoadAppSettings()
{
string serachPattern=
ConfigurationManager.AppSettings["AssemblySearchPattern"];
}
}
}
Console App: NetFx 4.6.X
using System;
using Bootstrapper.Lib;
namespace Bootstrapper.Console
{
class Program
{
static void Main(string[] args)
{
new Bootstrapper().LoadAppSettings();
}
}
}
Exception After Run:
'Could not load file or assembly 'System.Configuration.ConfigurationManager,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one
of its dependencies. The system cannot find the file specified.'
It will work with Console App developed using .NetCore.
Please help!!!
As #kiran mentioned in a comment you can solve this by running:
Install-Package System.Configuration.ConfigurationManager
in NuGet Package Manager
It is not possible to create .NET Standard library which references System.Configuration.ConfigurationManager package and uses ConfigurationManager class. Once library adds reference to .NET Core specific package it ceases to be portable .NET Standard library since it is bound to framework specific package.
.NET Standard 2.0 does not contain System.Configuration.ConfigurationManager API. Therefore, the only way to use this API is to build one version of the library against .NET Core System.Configuration.ConfigurationManager package which can be used on .NET Core and have a second version of the library which is build against .NET FX System.Configuration assembly and can be used on .NET FX.
Had the same issue and after installing the same System.Configuration.ConfigurationManager package in the FX4.6 project resolved this issue.
Alternative solutions are the following:
1. Copy .Net Standard dependencies
Add below line to your .Net Standard csproj file (Assembly 1) as described here.
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
Then rebuild Console App and System.Configuration.ConfigurationManager.dll with other dependencies of Assembly 1 will be copied to bin directory of Console App.
In my case it copies the below list of dlls
Interesting thing is that when I use another solution and install System.Configuration.ConfigurationManager NuGet package to FX4.6 Console App directly, I have another set of dependencies in result:
Notice that System.Configuration.ConfigurationManager.dll as well as other dlls have different size. As I understand, in first case it was copied from %userprofile%\.nuget\packages\system.configuration.configurationmanager\5.0.0\lib\netstandard2.0, but in second case from %userprofile%\.nuget\packages\system.configuration.configurationmanager\5.0.0\lib\net461
Anyway, both solutions work, so I'm not sure which is more correct.
or
2. Use multi-targeting
In your .Net Standard csproj file (Assembly 1) set second target to net461 as described here with line
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
Then on build two versions of library will be generated - in \bin\Release\net461 and in \bin\Release\netstandard2.0. If your Console App targets .Net Framework 4.6.1 or higher, it will automatically take correct version of Assembly 1 as dependency (the one from \net461).
The benefit of that approach is that net461 version of library doesn't require dependency from System.Configuration.ConfigurationManager.dll and can be distributed without it.

Categories