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
extern alias support for NuGet package references #4989
Comments
Great suggestion. I'll move this over to the NuGet repo, they own the syntax for PackageReference. |
This would be great since we are running into this issue due to https://www.nuget.org/packages/StackExchange.Redis/ and https://www.nuget.org/packages/StackExchange.Redis.StrongName/ |
We have this issue to if we want to add both of these |
@brianpos exactly the same problem here. |
@wburgers i have a project using the extern alias trick https://github.com/brianpos/FhirPathTester but do have to set manually after inclusion. So can't wait for this to be fixed. |
+1, can't wait for this. I think this is important because right now different packages implementing same namespaces. @brianpos could you share your trick please? |
IIRC you can configure NuGet to store the NuGet packages in an packages folder instead of using the cache in the users home folder using the NuGet.config. This allows you to manually specify project-relative assembly references (via |
Ok, so basically referencing the .dll quasi-manually and including then the alias, right? I was also thinking about that as a work around |
As a side note, a workaround is to write a target that does something like this: https://github.com/dotnet/project-system/blob/master/build/Targets/VSL.Imports.targets#L340. Here we're setting the EmbedInteropTypes metadata, but the same could be applied to alias. |
It would be great if someone on the NuGet team could point in the right direction of the repo that requires the change. I am sure people are happy to look if they know where to look. |
I think they'll need a design first, I don't see a flushed out proposal on syntax/behavior. Once we do that, we'll then need to work with the project systems (http://github.com/dotnet/project-system) and SDK (http://github.com/dotnet/project-system) to add/respect the property so that it can be passed to NuGet/show in Properties, etc, added to the |
I'll help sponsor, point to the locations that need to change in SDK, ProjectSystem (NuGet team will need to jump in on the nuget side, as I don't have context), and driving this through, if a community member wants to pick up the design/changes. |
After some experimentation and got it to work. Placed the below snippet into my csproj file where I had both references of <Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
<ReferencePath Condition="'%(FileName)' == 'StackExchange.Redis.StrongName'">
<Aliases>signed</Aliases>
</ReferencePath>
</ItemGroup>
</Target> |
@gertjvr sounds great! I will give it a try over here |
What would that entail? Sorry, I am not very familiar with the process! |
@gertjvr Just to clarify: |
@fubar-coder the target name is just a random name same goes for the alias signed, the snippet above was all I added to my csproj file. <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="4.6.0" />
<PackageReference Include="AutofacSerilogIntegration" Version="2.0.0" />
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.1.5" />
<PackageReference Include="AWSSDK.S3" Version="3.1.7.2" />
<PackageReference Include="ConfigInjector" Version="2.2.1175" />
<PackageReference Include="Linq2DynamoDb.DataContext" Version="2.0.0" />
<PackageReference Include="Linq2DynamoDb.DataContext.Caching.Redis" Version="2.0.0" />
<PackageReference Include="MassTransit" Version="3.5.7" />
<PackageReference Include="Microsoft.AspNet.SignalR.Core" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNet.SignalR.Redis" Version="2.2.2" />
<PackageReference Include="Microsoft.Owin" Version="3.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="Owin" Version="1.0.0" />
<PackageReference Include="Serilog" Version="2.5.0" />
<PackageReference Include="ThirdDrawer" Version="1.1.9" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
<ReferencePath Condition="'%(FileName)' == 'StackExchange.Redis.StrongName'">
<Aliases>signed</Aliases>
</ReferencePath>
</ItemGroup>
</Target>
</Project> |
…udio We don't need the split anymore now that we're only supporting Dev15. Unfortunately this required the introduction of a NuGet package that has a namespace "Workspace" to our VS project, which meant I had to disambiguate Workspace wherever it's used in that layer. I considered doing an extern alias instead to disambiguate, but applying that to a ProjectReference isn't supported. That's tracked by NuGet/Home#4989.
…udio We don't need the split anymore now that we're only supporting Dev15. Unfortunately this required the introduction of a NuGet package that has a namespace "Workspace" to our VS project, which meant I had to disambiguate Workspace wherever it's used in that layer. I considered doing an extern alias instead to disambiguate, but applying that to a ProjectReference isn't supported. That's tracked by NuGet/Home#4989.
I've tried this out with the Fhir assembly @ewoutkramer, works a treat. |
With dotnet/sdk#11612 and dotnet/sdk#11954, finally all the legs of this feature are completed. The feature will be available in 16.7 and all the matching tooling versions (3.1.400 of the SDK, 5.0 of the SDK) & 5.7 of NuGet.exe. If you are using NuGet.exe, keep in mind that you need VIsual Studio/ MSBuild to be 16.7 |
Awesome!! Thanks @nkolev92 for consistently following up on this one 👏 |
@nkolev92 can you please provide a link to the documentation / sample? |
@TFTomSun Design at https://github.com/NuGet/Home/blob/dev/designs/PackageReference-Extern-Alias.md. I'll update the docs by the time this ships in a GA release. |
@nkolev92 are the aliases transistive? I mean, are they applied to indirect, transistive dependencies, too? |
They only apply to the package reference they are specified on. The challenge with applying to transitive dependencies is the For the time being the answer to how do I apply metadata to a transitive package still remains |
Hi! |
@YanerTavuz Preview 3 should have it |
Got it to work with VS16.7 Preview 3.1 and .NET 5 Preview 6 with a .NET project SDK style. Trying to get it to work with .NET Framework 4.8 with old csproj style,, any tips on how to get it working there? @nkolev92 Edit: After some investigating, it seems that the dll for Microsoft.NuGet.Build.Tasks that is shipped with Visual Studio 16.7 Preview 3.1 does not contain your changes from dotnet/NuGet.BuildTasks#70 so I guess that's the issue. |
Will this work to alias different versions of the same package? |
Yes |
No, this cannot be used to alias different versions of the same package that has the same identifier. This is entirely used to alias assemblies within a package. |
@davkean Is there any plan to enable this in the case of "different version of same nuget package"? This would be very handy for versioning classes and allowing a single service to interop with both (or many versions) concurrently using aliases. |
@tdhatcher I'm aware of no plans to allow the ability to reference multiple versions of the same NuGet packages, but one of the NuGet folks would need to chime in, @nkolev92 . |
There are no active plans to enable multiple versions of the same package in a project at this point. |
@nkolev92 my feedback is as someone who is not familar with inner workings of nuget package resolution. I'm curious if this doesn't exist because it's more of a technical hurdle to accomplish or more of a logical decision? It seems if two or more distinctly named packages can resolve namespace collision with aliases then two or more of the same named packages should be able to resolve namespace collision. I haven't really come across a solid prescribed strategy as for how to actually implement your API versions especially when breaking changes are present (and without separately hosting older version of the API). Just that there is flexibility in ASP.NET Core to support mapping multiple API versions to different controllers to handle the request/response (concurrently in the same running instance of an API). Consider a common scenario when you publish a nuget package that serves as a convenient SDK for your API. That SDK contains all the classes that act as the contracts and client for consumers to interact with the API. The version of the SDK's nuget package is kept in-sync with the version of the API (eg. you'd use version 5 of the SDK you are communicating with v5 of the API). By allowing aliases on same Nuget package with different versions, the API implementation would be able to reference the proper version of the SDK nuget package to obtain the proper contracts for the specific version of API controllers. This approach would be in contrast to an approach of maintaining a versioned yet disjointed SDK library separately while in the API it is cloning/maintaining multiple versions of the contracts globbed together in a single project to support backwards compatibility. Seems like a clean option like this is missing. Allowing aliases for the same package but different versions would be a very complementary feature to ASP.NET Core API versioning. https://github.com/dotnet/aspnet-api-versioning/wiki/Existing-Services-Quick-Start |
@tdhatcher Having multiple versions of the same assembly (by extension of package) is a pretty involved feature. I won't be able to address all your concerns, but one difficult challenge is what happens transitively. Sure if you reference a package directly, you can choose to alias it's assemblies, but what happens for the transitive dependencies that might have some incompatibilities? You're likely to need some sort of assembly rewriting to make this work, which would have it's own set of problems. If you'd like you can file a different issue with that ask. The first thing that would need to happen to make progress on your idea is for the tooling overall to support |
@tdhatcher I appreciate the callout 😉 , but an API version is not like a Semantic Version or assembly version; this is a false equivalency. Backward compatibility should in no way be implied or inferred from any API version. This is a common misconception. The rules for versioning binaries are quite different and are well-known across many languages and tools. These rules do not generically apply to an API. Even if the changes to the message body of an API is additive, a server cannot guarantee that the client implements a tolerant reader and will not break. There's nothing about API authors that vend a client that they want to have affinity to the API version usually take one of the following approaches:
While it is possible, it's usual and uncommon to need multiple versions of the same API simultaneously. Azure SDKs are backed by versioned Azure APIs. When you use a particular version of the client SDK, you typically don't think about the backing API version and certainly not multiple API versions at the same time. As @nkolev92 mentioned, the complexity of SxS assemblies is involved and goes beyond just aliasing. Even if you got it to work, it's pretty painful for package consumers. I doubt many would actually want that. There are like other ways to achieve your goals, including, but not limited to having a clearly defined API versioning policy such as |
From @fubar-coder on April 5, 2017 15:59
Currently, when a NuGet package reference is added, there is no way to set the alias from the project system for the new style csproj projects.
This feature is needed, because NuGet package references don't result in direct assembly references any more and only those can have an alias.
My proposal is to add the alias(es) to all assemblies referenced for the NuGet package, but not the indirectly referenced NuGet packages.
Copied from original issue: dotnet/project-system#1930
notes
dotnet/sdk#10947 The build tasks on (.NET Core SDK side)
dotnet/NuGet.BuildTasks#70 The build tasks for the non-SDK based PackageReference
dotnet/project-system#6011 Nomination updates on project-system side.
The text was updated successfully, but these errors were encountered: