Open aortiz-msft opened 3 years ago
Issue moved from NuGet/Home#10438
From @JonDouglas on Friday, January 8, 2021 5:49:15 PM
Hi @weltkante,
Thanks for the report!
Can you please provide us a sample project or reproducible steps to help us debug this further?
Feel free to refer to our section on bug reports for more information on what we're looking for!
Issue moved from NuGet/Home#10438
From @weltkante on Friday, January 8, 2021 7:25:18 PM
Sure, the reproduction steps are literally just what I said above, adding a PackageReference
to a framework package and a corresponding extern alias
statement. I'm adding a full example below, changing the SDK to Microsoft.NET.Sdk
(i.e. removing the Web
) makes things compile but obviously I'm then missing a lot of implicit behavior of the Web SDK, both in implicit package references and project system behavior.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" Aliases="logging" />
</ItemGroup>
</Project>
extern alias logging;
using System;
namespace PackageAlias
{
public class Helper
{
public void MethodWithLogger(logging::Microsoft.Extensions.Logging.ILogger logger)
{
}
}
}
Program.cs(1,14,1,21): error CS0430: The extern alias 'logging' was not specified in a /reference option
Program.cs(9,47,9,56): error CS0234: The type or namespace name 'Microsoft' does not exist in the namespace 'logging' (are you missing an assembly reference?)
Issue moved from NuGet/Home#10438
From @JonDouglas on Friday, January 8, 2021 8:14:16 PM
@weltkante Thank you kindly! We'll look into this shortly in our next triaging session. Thanks for the clarification on the .csproj items!
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I've never in my life needed to use extern alias
before but when I do of course it's completely broken. The Aliases
property has no effect in net48 or net5.0 projects. Visual Studio 16.8.5.
I'm now getting tripped up on this too. net5.0 project.
I'm also having this problem. The context is I am making a library that has multiple TFMs.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net472</TargetFrameworks>
</PropertyGroup>
<!-- Conditional PackageReferences are in here with Aliases set -->
</Project>
There is a type I need that exists in the same namespace but different assemblies, so I need an external alias
. But this won't work as one of my targets is net472
.
Migrating some code from <Reference>
to <ProjectReference>
I stumbled across this also.
Any update on this issue?
I face similar issue:
`
The Aliases within ProjectReference doesn't work. Have this issue:
Error CS0430 The extern alias 'MyProjectDS' was not specified in a /reference option
`
While the Aliases for PackageReference works:
`
<Aliases>EC</Aliases>
<Private>True</Private>
</Reference>
`
Dear @wli3, Do you have any updates or suggestions to work around it?
This looks like a related issue. https://github.com/dotnet/msbuild/issues/4943
Problem
Only the extern alias
of the first occurrence of NuGet PackageReference is recognized v12. v11 results in compilation error CS0430
Reproduce Steps
csproj
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" Aliases="v12" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" Aliases="v11" />
</ItemGroup>
Program.cs (C# 11 / NET 7)
extern alias v12;
extern alias v11;
using Json12 = v12::Newtonsoft.Json; using Json11 = v11::Newtonsoft.Json;
Json12.JsonConvert.SerializeObject(new { message = "Hello, world!" }); Json11.JsonConvert.SerializeObject(new { message = "Hello, world!" });
I even stumped ChatGPT with this one, it seemed so confident that it _should be_ working and that I was doing something wrong.
<img width="551" alt="image" src="https://user-images.githubusercontent.com/360359/215599662-8efc7987-e633-49c4-8020-ec9f9d965b9d.png">
I'm assuming this is a dead issue that will never be addressed?
Still busted, my project is net472.
Confirmed that this still does not work. I tried to do this with .NET 8.0.2 using a regular NuGet package, and extern alias throws CS0430.
Any updates on this? I am trying to write a test to compare multiple versions of the same library, but this is making it impossible.
Any updates on this? I am trying to write a test to compare multiple versions of the same library, but this is making it impossible.
That was exactly what I was trying to do. Didn't work for me because if I loaded the csproj and the NuGet package at the same time, the NuGet package simply wouldn't get loaded.
For me it is two versions of a local project. I have the same issue regardless of whether I use a ProjectReference
or a Reference
. In both cases, it is the later include that works, and the alias for the earlier one is not found (so, if I swap the order, then the later one is still the only one found).
<ItemGroup Label="Project References">
<ProjectReference Include="../old/MyProject.csproj">
<Aliases>OldCode</Aliases>
<Project>{D82F0573-0863-47A0-8280-0C0FEE65BD0F}</Project>
</ProjectReference>
<ProjectReference Include="../new/MyProject.csproj">
<Aliases>NewCode</Aliases>
<Project>{83895685-5E0B-447E-8560-4CD0DA32E2A6}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup Label="References">
<Reference Include="MyProject">
<Aliases>OldCode</Aliases>
<HintPath>../old/bin/Debug/net7.0/MyProject.dll</HintPath>
</Reference>
<Reference Include="MyProject">
<Aliases>NewCode</Aliases>
<HintPath>../new/bin/Debug/net7.0/MyProject.dll</HintPath>
</Reference>
</ItemGroup>
Take a look here: https://jeanarjean.com/blog/2021-03-10-how-to-create-alias-property-in-your-csproj/
I wasn't able to get the whole thing working because of my own scenario, but the key seems to be be that you have call your classes using the :: convention.
extern alias CustomNamespace1
extern alias CustomNamespace2
using CustomNamespace1::whatevernamespace.youwant;
using CustomNamespace2::whatevernamespace.youwant;
Yes, that is exactly what I did. No luck.
For:
extern alias OldCode;
extern alias NewCode;
I get the error:
error CS0430: The extern alias 'OldCode' was not specified in a /reference option
Yea, that's where I end up as well.
@wli3 @aortiz-msft - any update or progress on this? This issue is 3 years old at this point. While certainly not something I've ever had to do until now, it's quite obviously completely broken without any viable alternative/workaround.
Thanks, Justin Carman
FWIW I reproduced on the Nuget.Versioning
example that is linked in the microsoft docs:
Their example only has one alias, but if you add a second one it has the same was not specified in a /reference option
error. What is the use of only having one alias?
Also, does anyone know if the Aliases
option was intended to work with central package management? I had something akin to:
<ItemGroup>
<PackageReference Include="NuGet.Versioning" VersionOverride="5.8.0" Aliases="ExampleAlias" />
<PackageReference Include="NuGet.Versioning" VersionOverride="6.10.0" Aliases="Latest" />
</ItemGroup>
(Note the VersionOverride
instead of Version
)
I originally thought my error was due to this package being defined already in Directory.Packages.props
but sounds like that is unrelated and this should still work.
Including recent top dotnet/sdk contributor @v-wuzhai to see if this can be reassigned to an active contributor to investigate this (or to include other active contributors for their thoughts) as there has been no notable feedback here from contributors and this ticket is almost 3.5 years old.
@marcpopMSFT @dsplaisted also tagging a couple other recent top dotnet/sdk contribs for the same reason.
Triage: There are two scenarios outlined in this issue. Extern alias was originally designed to use two different assemblies that have the same name. Neither case above is that exact case and it was not designed for that.
We'd like to understand the why of the original scenarios. For the original issue, why would a customer need to reference two versions of the shared framework and require the alias so as to use both logging dlls? We now have namespace aliasing now that might satisfy some of the usages the customer was trying to achieve back in 5: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive
For the second scenario, we do not believe that nuget supports referencing two different versions of the same package. That seems to be the more common request from later commentors. CC @nkolev92 @aortiz-msft
For the original issue, why would a customer need to reference two versions of the shared framework and require the alias so as to use both logging dlls?
As the OP, this was not my scenario, I simply needed to give an assembly an alias to resolve a naming conflict (same namespace and typename used in different assemblies). I did not need to load the same assembly twice or in different versions.
Extern alias was originally designed to use two different assemblies that have the same name.
Given that it just drops the alias (instead of merging it) when it resolves the package references in msbuild, I don't think it was "designed" at all, certainly it is not compatible with modern msbuild grouping and resolution of package references.
As for the other people who posted over the years, can't speak for their use-cases.
Extern alias was originally designed to use two different assemblies that have the same name.
This is specifically my complaint for what is broken so I am glad to see confirmation that it is indeed supposed to work for my use case. So, I think this is the behavior that we need to investigate for a bug fix.
The reason for why I need this to work is so that I can write tests to compare the output from two builds of the same library (same assembly name). But I suppose the reasoning is moot since you are confirming that it is broken based on how it was originally designed vs how it is functioning now.
My comment here explains the failing behavior in a little more detail: https://github.com/dotnet/sdk/issues/15443#issuecomment-1956748678
For me it is two versions of a local project. I have the same issue regardless of whether I use a
ProjectReference
or aReference
. In both cases, it is the later include that works, and the alias for the earlier one is not found (so, if I swap the order, then the later one is still the only one found).<ItemGroup Label="Project References"> <ProjectReference Include="../old/MyProject.csproj"> <Aliases>OldCode</Aliases> <Project>{D82F0573-0863-47A0-8280-0C0FEE65BD0F}</Project> </ProjectReference> <ProjectReference Include="../new/MyProject.csproj"> <Aliases>NewCode</Aliases> <Project>{83895685-5E0B-447E-8560-4CD0DA32E2A6}</Project> </ProjectReference> </ItemGroup>
<ItemGroup Label="References"> <Reference Include="MyProject"> <Aliases>OldCode</Aliases> <HintPath>../old/bin/Debug/net7.0/MyProject.dll</HintPath> </Reference> <Reference Include="MyProject"> <Aliases>NewCode</Aliases> <HintPath>../new/bin/Debug/net7.0/MyProject.dll</HintPath> </Reference> </ItemGroup>
And my comment here provides a little more detail in relation to that: https://github.com/dotnet/sdk/issues/15443#issuecomment-1956781994
Yes, that is exactly what I did. No luck.
For:
extern alias OldCode; extern alias NewCode;
I get the error:
error CS0430: The extern alias 'OldCode' was not specified in a /reference option
I have also run into other issues when trying to load both versions of the assembly via reflection, which throws errors due to the same assembly name being registered multiple times. So, I am also unable to use reflection as a workaround for an alternate approach to the explicit assembly references.
Extern alias was originally designed to use two different assemblies that have the same name.
This is specifically my complaint for what is broken so I am glad to see confirmation that it is indeed supposed to work for my use case. So, I think this is the behavior that we need to investigate for a bug fix.
This is also my use case, except that it's to compare my current build with my last published NuGet package to be able to do performance regression testing.
In my case we were moving from old project format to new project format. Two assemblies, neither built by my team so I couldn't change them, contained the same namespace with the same class, and an alias was used to resolve this. I don't remember the details of why they had the same namespace, but probably because we implemented, like many do, a Smurf naming convention in namespaces.
After converting to the new project format the alias no longer worked, so we couldn't move forward with the project format change because it would no longer build. We wanted to move to the new project format, and PackageReference over packages.config. Because our build system was a Rube Goldberg machine (I guess like most build systems) and we frequently got runtime errors from binding redirects caused by packages.config being out of sync with the project file. Tracking those issues down was very time consuming.
Triage: Thank you all for the comments here. For the scenario of same assembly but different versions, it sounds like there is a valid use case there but not what this feature was designed for. Please file a separate issue that we will put on the backlog and use to gather feedback for potentially revisiting in the future.
Let's keep this issue focused on the original report which should be supported and we'll need some time to investigate why it's not working.
CC @nkolev92
Issue moved from NuGet/Home#10438
From @weltkante on Friday, January 8, 2021 4:19:41 PM
Details about Problem
In #4989 alias support for PackageReference was added, but when I try to create an alias to a framework-provided package this does not appear to work.
In particular, in a .NET 5 web application I add
but
extern alias logging;
does not compile:If I instead do it in a console application it indeed does work.
Using VS 2019 Update 9 Preview 2