NuGet / Samples

NuGet team sample repo
Other
136 stars 108 forks source link

How to add extern alias for three same namspace assemblies #39

Closed dhinesh-v closed 4 years ago

dhinesh-v commented 4 years ago

Using the below sample, I can able to alias two assemblies. But is this possible to alias three assemblies.

https://github.com/NuGet/Samples/blob/master/ExternPackageReference.Example/ConsoleApp/ConsoleApp.csproj

zivkan commented 4 years ago

Try something like this

  <Target Name="AddCustomAliases" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)' == 'Assembly1' AND '%(ReferencePath.NuGetPackageId)' == 'ClassLib2'">
        <Aliases>alias1</Aliases>
      </ReferencePath>
      <ReferencePath Condition="'%(FileName)' == 'Assembly2' AND '%(ReferencePath.NuGetPackageId)' == 'ClassLib2'">
        <Aliases>alias2</Aliases>
      </ReferencePath>
      <ReferencePath Condition="'%(FileName)' == 'Assembly3' AND '%(ReferencePath.NuGetPackageId)' == 'ClassLib2'">
        <Aliases>alias3</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

Change the assembly and package ids as necessary.

dhinesh-v commented 4 years ago

Hi @zivkan ,

I have tried your solution, but only one alias is working, Other aliases are not working and showing below error,

The extern alias 'LatestCore' was not specified in a /reference option

Also I have tried below solution,

<Target Name="AddPackageAliases" BeforeTargets="ResolveReferences" Outputs="%(PackageReference.Identity)">
    <PropertyGroup>
        <AliasPackageReference>@(PackageReference->'%(Identity)')</AliasPackageReference>
        <AliasName>@(PackageReference->'%(Alias)')</AliasName>
    </PropertyGroup>

    <ItemGroup>
        <ReferencePath Condition="'%(FileName)'=='$(AliasPackageReference)'">
            <Aliases>$(AliasName)</Aliases>
        </ReferencePath>
    </ItemGroup>
</Target>

<ItemGroup>
     <PackageReference Include="KeyGen_Old.Core" Version="1.0.0" Alias="OldCore" />
     <PackageReference Include="KeyGen.Core" Version="2.0.0" Alias="Core" />
     <PackageReference Include="KeyGen_Latest.Core" Version="3.0.0" Alias="LatestCore" />
</ItemGroup>

But same problem happens.

zivkan commented 4 years ago

This worked for me at build, but intellisense doesn't know about the aliases

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NuGet.Frameworks" Version="5.5.0" />
    <PackageReference Include="NuGet.Versioning" Version="5.5.0" />
  </ItemGroup>

  <Target Name="AddCustomAliases" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)' == 'NuGet.Frameworks' AND '%(ReferencePath.NuGetPackageId)' == 'NuGet.Frameworks'">
        <Aliases>alias1</Aliases>
      </ReferencePath>
      <ReferencePath Condition="'%(FileName)' == 'NuGet.Versioning' AND '%(ReferencePath.NuGetPackageId)' == 'NuGet.Versioning'">
        <Aliases>alias2</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

</Project>
extern alias alias1;
extern alias alias2;

using System;

namespace aliasTest
{
    public class Class1
    {
        public void DoNothing()
        {
            var netstandard2_0 = alias1.NuGet.Frameworks.FrameworkConstants.CommonFrameworks.NetStandard20;
            var allStable = alias2.NuGet.Versioning.VersionRange.AllStable;
        }
    }
}

If you need to debug, I suggest running a build with the -bl option (dotnet build -bl or msbuild -bl), then open the msbuild.binlog file with the MSBuild binary log viewer. You can then look around to understand why the ReferencePath items are not getting the correct aliases metadata.

dhinesh-v commented 4 years ago

@zivkan Thank you so much for helping me here, I'm really sorry that i didn't clearly explain the issue.

I can able to alias two assemblies which has different namespace. But i want to alias three assemblies which have same namespace.

zivkan commented 4 years ago

My example shows the concept. I don't know two packages on nuget.org that contain types in the same namespace, so I used NuGet.Versioning and NuGet.Frameworks as an example. But you can see in the C# file that it uses alias1 and alias2 and the code compiles, meaning the compiler was passed both alias names.

As I mentioned in the last paragraph of my example, you can use MSBuild's binary logs to check the ReferencePath items have the correct metadata:

image

Similarly on the Csc task, I can see /reference:alias1=C:\git\test\globalPackages\nuget.frameworks\5.5.0\lib\netstandard2.0\NuGet.Frameworks.dll /reference:alias2=C:\git\test\globalPackages\nuget.versioning\5.5.0\lib\netstandard2.0\NuGet.Versioning.dll

If you're getting the same alias on the assembly from different packages, I assume that you removed the AND '%(ReferencePath.NuGetPackageId)' == 'NuGet.Frameworks' part of the condition.

You can also add <Message Text="whatever" to add tracing information to help you debug your target.

zivkan commented 4 years ago

Closing as you're also engaging with us at https://github.com/NuGet/Home/issues/4989

In case it helps, msbuild doesn't know anything about .NET namespaces, that's a compiler issue. MSBuild is just a scripting language to run a bunch of tasks (the compiler is one task), by getting lists of files and generating task input parameters. So, it has no way of knowing whether two assemblies you want to use aliases on have the same or different namespaces inside.