Genbox / SimpleS3

A .NET Core implementation of Amazon's S3 API with focus on simplicity, security and performance
MIT License
50 stars 8 forks source link

Bug: It is tricky to use the packages in .NET Core 2.x (and 3.x), due to package constraints #41

Closed LordMike closed 3 years ago

LordMike commented 3 years ago

Describe the bug When utilizing SimpleS3 in an ASP.Net Core web app, targeting netcoreapp2.2 (yes yes, I know).. SimpleS3 conflicts with ASP.Net's dependencies. It turns out, that ASP.Net expects packages like Microsoft.Extensions.DependencyInjection in the rather short range >=2.2.0 .. <2.3.0. Kinda makes sense due to MS's versioning, but it makes it tricky for use cases like this.

How to reproduce? Create any ASP.Net web project targeting less than .NET 5 - the issue should appear like build errors with the following:

Version conflict detected for Microsoft.Extensions.DependencyInjection. Install/reference Microsoft.Extensions.DependencyInjection 5.0.0 directly to project MyWeb.App to resolve this issue. MyWeb.App -> Genbox.SimpleS3.Core 1.1.1 -> Microsoft.Extensions.Logging 5.0.0 -> Microsoft.Extensions.DependencyInjection (>= 5.0.0) MyWeb.App -> Microsoft.AspNetCore.App 2.2.0 -> Microsoft.Extensions.DependencyInjection (>= 2.2.0 && < 2.3.0).

Once that is resolved, by using 5.x packages directly, the next package is an issue, like Microsoft.Extensions.DependencyInjection.Abstractions (which is depended on by the former..)..

Expected behavior I expected SimpleS3 to be very lenient in its dependencies, to be as accomodating as possible. Nuget unfortunately has a habit of picking the lowest version applicable (presumably to make as stable experiences as possible). Three immediate courses of action spring to mind:

Example ASP.Net package's nuspec range: https://www.fuget.org/packages/Microsoft.AspNetCore.App/2.2.0

<dependency id="Microsoft.Extensions.DependencyInjection" version="[2.2.0, 2.3.0)" include="All" />
Genbox commented 3 years ago

I didn't know Microsoft had limited ASP.net to a certain version range on packages.

The floating version solution requires NuGet to fetch all versions of a package to determine which version to use. It is not a big problem admittedly, but it might be. I'm also unsure how exactly the dependency resolution happens in real life on larger projects if I force NuGet to resolve to the latest version of dependencies. One thing is SimpleS3's dependencies where floating versions seem to be a convenience that auto-select newer versions, another is how projects that depend on SimpleS3 use the information to resolve dependencies.

The lowest package seems like an easy solution, unless I need particular features from a newer version of the package. It so happens I don't really need anything that was added since .NET 2.1, but if it happens, I have to choose between using the feature and backward compatibility - not because of breaking changes, but because Microsoft apparently doesn't like packages to be shared between framework versions.

The multi-targeting solution would seem to work for the problem mentioned above. If a newer package has a feature I need, I could multitarget the library to only use the feature if the consumer targets a certain framework. However, it seems cumbersome to maintain a matrix of supported frameworks.

For now, I've opted to depend on the lowest supported packages (2.1) - see https://dotnet.microsoft.com/platform/support/policy/dotnet-core