NuGet package has missing/incorrect dependencies
OronDF343 opened this issue · 4 comments
Describe the bug
The NuGet package Vonage 6.1.0
is missing a depndency on Enums.NET >= 4.0.0
(and possibly other packages). This causes an exception when sending requests with VonageClient
(for example, WhatsApp templates).
The cause of the issue is that the dependencies in Vonage.csproj
do not match those in Vonage.Common.csproj
.
To Reproduce
Steps to reproduce the behavior:
- Create a new .NET 6.0 console application
- Install package
Vonage 6.1.0
- Write some code that uses VonageClient in
Program.cs
:
using Vonage;
using Vonage.Messages.WhatsApp;
var creds = Vonage.Request.Credentials.FromApiKeyAndSecret(...);
var vonage = new VonageClient(creds);
var item = new WhatsAppTemplateRequest
{
...
};
var res = await vonage.MessagesClient.SendAsync(item);
Console.WriteLine(res.MessageUuid);
- Debug the application. An exception is thrown:
System.IO.FileNotFoundException: Could not load file or assembly 'Enums.NET, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7ea1c1650d506225'. The system cannot find the file specified.
Expected behavior
The NuGet package should function correctly out of the box, without manually installing additional 3rd-party packages.
Stack trace
System.IO.FileNotFoundException
HResult=0x80070002
Message=Could not load file or assembly 'Enums.NET, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7ea1c1650d506225'. The system cannot find the file specified.
Source=Vonage.Common
StackTrace:
at Vonage.Common.Serialization.EnumDescriptionJsonConverter`1.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs:line 355
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs:line 309
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs:line 306
at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs:line 440
at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.WriteCore.cs:line 47
at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.WriteCore.cs:line 36
at System.Text.Json.JsonSerializer.WriteCore[TValue](Utf8JsonWriter writer, TValue& value, JsonTypeInfo`1 jsonTypeInfo) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs:line 46
at System.Text.Json.JsonSerializer.WriteString[TValue](TValue& value, JsonTypeInfo`1 jsonTypeInfo) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs:line 141
at Vonage.Messages.MessagesClient.<>c.<SendAsync>b__4_1(Object value)
at Vonage.Request.ApiRequest.<DoRequestWithJsonContentAsync>d__18`1.MoveNext()
at Program.<<Main>$>d__0.MoveNext() in ...Program.cs:line 21
at Program.<Main>(String[] args)
Desktop:
- Windows 10 22H2
- Visual Studio 2022 Professional 17.5.3
- .NET SDK 6.0.407, Runtime 6.0.15
Additional context
In my opinion, the problem is more than just 1 missing dependency. See Vonage.csproj and Vonage.Common.csproj - The dependencies of the latter do not appear in the NuGet package.
Now, take a look at how many transient dependencies are installed with this package:
Installing:
jose-jwt.4.1.0
Microsoft.AspNetCore.WebUtilities.2.2.0
Microsoft.Extensions.Configuration.7.0.0
Microsoft.Extensions.Configuration.Abstractions.7.0.0
Microsoft.Extensions.Configuration.FileExtensions.7.0.0
Microsoft.Extensions.Configuration.Json.7.0.0
Microsoft.Extensions.DependencyInjection.7.0.0
Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0
Microsoft.Extensions.FileProviders.Abstractions.7.0.0
Microsoft.Extensions.FileProviders.Physical.7.0.0
Microsoft.Extensions.FileSystemGlobbing.7.0.0
Microsoft.Extensions.Logging.7.0.0
Microsoft.Extensions.Logging.Abstractions.7.0.0
Microsoft.Extensions.Options.7.0.0
Microsoft.Extensions.Primitives.7.0.0
Microsoft.Net.Http.Headers.2.2.0
Microsoft.NETCore.Platforms.1.1.1
Microsoft.NETCore.Targets.1.1.0
Microsoft.Win32.Primitives.4.3.0
Microsoft.Win32.Registry.4.3.0
Newtonsoft.Json.13.0.2
runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.native.System.4.3.0
runtime.native.System.Net.Http.4.3.0
runtime.native.System.Security.Cryptography.Apple.4.3.1
runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple.4.3.1
runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl.4.3.2
System.Buffers.4.5.0
System.Collections.4.3.0
System.Collections.Concurrent.4.3.0
System.Collections.Immutable.7.0.0
System.ComponentModel.4.3.0
System.ComponentModel.Annotations.5.0.0
System.ComponentModel.Composition.7.0.0
System.Diagnostics.Debug.4.3.0
System.Diagnostics.DiagnosticSource.4.3.0
System.Diagnostics.Process.4.3.0
System.Diagnostics.Tracing.4.3.0
System.Formats.Asn1.5.0.0
System.Globalization.4.3.0
System.Globalization.Calendars.4.3.0
System.Globalization.Extensions.4.3.0
System.IO.4.3.0
System.IO.Abstractions.19.1.18
System.IO.FileSystem.4.3.0
System.IO.FileSystem.Primitives.4.3.0
System.Linq.4.3.0
System.Net.Http.4.3.4
System.Net.Primitives.4.3.0
System.Reflection.4.3.0
System.Reflection.Primitives.4.3.0
System.Resources.ResourceManager.4.3.0
System.Runtime.4.3.0
System.Runtime.CompilerServices.Unsafe.6.0.0
System.Runtime.Extensions.4.3.0
System.Runtime.Handles.4.3.0
System.Runtime.InteropServices.4.3.0
System.Runtime.Numerics.4.3.0
System.Security.Cryptography.Algorithms.4.3.1
System.Security.Cryptography.Cng.5.0.0
System.Security.Cryptography.Csp.4.3.0
System.Security.Cryptography.Encoding.4.3.0
System.Security.Cryptography.OpenSsl.5.0.0
System.Security.Cryptography.Primitives.4.3.0
System.Security.Cryptography.X509Certificates.4.3.0
System.Text.Encoding.4.3.0
System.Text.Encoding.Extensions.4.3.0
System.Text.Encodings.Web.7.0.0
System.Text.Json.7.0.0
System.Threading.4.3.0
System.Threading.Tasks.4.3.0
System.Threading.Thread.4.3.0
System.Threading.ThreadPool.4.3.0
TestableIO.System.IO.Abstractions.19.1.18
TestableIO.System.IO.Abstractions.Wrappers.19.1.18
Vonage.6.1.0
Yoh.Text.Json.NamingPolicies.1.0.0
Here's what's wrong in my opinion:
- All of the System.* packages with version 4.3.x are not needed for any currently supported .NET platform. They are used only for .NET Core 1.x. (Vonage references some of these, which bring in all of the others via legacy DNX5.0 TFMs. .NET Framework is not affected by this)
- Vonage references both
Newtonsoft.Json
(directly) andSystem.Text.Json
(viaYoh.Text.Json.NamingPolicies
). There is no reason to reference both of these at the same time outside of migration of legacy code (same functionality). - The legacy package
Microsoft.AspNetCore.WebUtilities
is referenced directly (no longer maintained since .NET Core 2.x)
Here's what I think needs to happen:
- The dependencies of the NuGet package should be the union of the dependencies of
Vonage.csproj
andVonage.Common.csproj
. - Please consider using multi-targeting with conditional references. This is the approach recommended by Microsoft, and will help with utilizing modern .NET features better.
- Unless .NET Core 1.x compatibility is required, consider removing all of the System.* dependencies that are version 4.3.x. Especially
System.Net.Http
as referencing this package is known to cause issues with binding redirects in .NET Framework. - Verify whether it is actually necessary to reference both
Newtonsoft.Json
andSystem.Text.Json
Hi @OronDF343,
Thanks for letting us know. I'll take a look into that today, and I'll get back to you asap.
@OronDF343 I released a new version, v6.2.0, today that fixes the problem. Thanks a lot for highlighting it!
Thanks also for bringing up all these points. Here's what I can share at the moment:
- System packages with version
4.3.x
=> We had plenty of those. The main project was migrated from specific frameworks to netstandard2.0 a few versions ago, and dependency cleaning has been forgotten. Newtonsoft
vs.System.Text.Json
=> Good catch - the goal is to migrate to System.Text.Json, but we're iterating on that, given it's a high investment to do everything at once. This is a temporary situation (hard to give a forecast, though), and it explains why we currently have both dependencies. Still, it shouldn't affect you from a consumer perspective, given it's all in the internals.Microsoft.AspNetCore.WebUtilities
=> The only reason we depend on that is to benefit fromQueryHelpers
. Sticking to netstandard2.0 means we can't benefit from Net6.0 and above, and that's a shame. I'll keep it on my radar to maybe re-implement something internally and remove this dependency.- The package dependency should be the union of dependencies => I absolutely agree. I thought it was currently the case, but it looks like this one slipped through the net. The way the package is created is a bit weird regarding nested projects, and it requires us to do the following to include Vonage.Common
vonage-dotnet-sdk/Vonage/Vonage.csproj
Lines 89 to 92 in 980bff4
- Multi-targeting =>Indeed, but this shouldn't be required for us anymore. As I mentioned above, the package only complies towards netstandard2.0, and this should make it easy for us.
I hope I have brought some light on the situation.
Happy to talk about it further 😄 And thanks again for reporting the issue!
@Tr00d Thanks a lot for the quick response! The new version improves a lot.
Looking into things further, I agree that multi-targeting would not do much for this package as it is today. If, however, it becomes desirable to use it in the future (e.g. to take advantage of net6.0 features conditionally), this workaround will work for including the Vonage.Common dll in the package per target framework automatically.
@OronDF343 Thanks for that! I'll keep an eye on it.
Normally, this is a temporary situation. We have another package generated from this repository (Vonage.Server
), representing a beta for our Video features. The package Vonage.Common
appeared to allow code reuse and avoid duplication. Once the beta "ends", we shall move back to a single project.