24

TLDR: Everything is pretty much in the title.

Suppose that your project.json uses two packages that have a two types which are named the same (same name, same namespace).

How to use one of thoses types ?

With classing .Net, that's easy. Just use an extern alias.

But how do you do that using .net core ? I dont see any option in package.json that would let me define an alias like I would do in an assembly reference property window.

The only mention of this issue i managed to find is here

[edit] It seems that there is an open issue here

Olivier
  • 5,578
  • 2
  • 31
  • 46

5 Answers5

13

I believe the issue you are trying to link to is here:
https://github.com/NuGet/Home/issues/4989

You can workaround by using an MSBuild Target. drop this snippet into Directory.Build.targets:

<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>

and then use it in your csproj in your PackageReference nodes like this:

<ItemGroup>
    <PackageReference Include="StackExchange.Redis.StrongName" Version="1.2.6" Alias="signed" />
</ItemGroup>

added this as a comment to the GitHub issue:
https://github.com/NuGet/Home/issues/4989#issuecomment-426666530

Dave Thieben
  • 5,388
  • 2
  • 28
  • 38
  • yep, that was the issue. i editted my question. I did not test your solution, but it looks like something that works, i'll accept that :) – Olivier Oct 03 '18 at 15:57
  • were is it the "Directory.Build.targets"? – isaeid Jan 15 '19 at 11:10
  • Were is it "Directory.Build.targets', in which file? – isaeid Jan 15 '19 at 14:38
  • `Directory.Build.targets` is an MSBuild file you create in you solution dir. if it is present, it will get loaded into your build. if you only need this in one project, you can add it to your `csproj`, but if you have multiple projects, adding it into this file will allow it to be used from any project in your solution. – Dave Thieben Jan 15 '19 at 18:14
  • @davethieben could you please complete your answer? After creating the `Directory.Build.targets` and setting the alias (`signed`) in my `.csproj` I'm trying to do `extern alias signed` in a C# file but it's not recognized by the compiler. What am I missing? Thanks – Jérôme MEVEL Mar 06 '19 at 05:56
  • make sure it's the first line in the file, or I was seeing: `An extern alias declaration must precede all other elements defined in the namespace`. then fully qualify the Type declaration like `signed::Namespace.Type myType` – Dave Thieben Mar 07 '19 at 17:58
  • @davethieben Ok I closed and reopened VS then I was doing some testing with a `` and then at some point it started working. Beside that I honestly don't know what did I do to solve the issue. Thanks for the help! – Jérôme MEVEL Mar 08 '19 at 02:16
  • And then it stopped working when I switched Git branch and did it on the library I want. So weird can't explain it for the moment. I will figure this out another time, this task has been postponed anyway... – Jérôme MEVEL Mar 08 '19 at 02:32
  • 1
    @davethieben I'm getting the below error and unable to solve. Could you please help Error CS0430: The extern alias 'signed' was not specified in a /reference option – Suresh Raja Mar 17 '20 at 01:26
7

I had a problem in .Net Core 2.2 where the MySqlConnector type name and namespace had a collision and the answer was to create an alias. I think this should work for your needs too, just change MySqlConnector below accordingly: https://stackoverflow.com/a/48686823/479701

<Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)' == 'MySqlConnector'">
        <Aliases>MySqlConnectorAlias</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

then in your cs file before usings:

extern alias MySqlConnectorAlias;

then reference your type like this:

MySqlConnectorAlias::MySql.Data.MySqlClient.MySqlConnection
Andy Raddatz
  • 2,792
  • 1
  • 27
  • 29
6

There's no need for all these workarounds anymore. You can now use alias in dotnet from v16.7+. Details here.

So none of the workarounds here are required anymore. Simply add the alias into your project file (intelli-sense didn't seem to think this existed but it works):

<ProjectReference Include="Example.csproj" Aliases="ExampleAlias" />

then use the extern alias ExampleAlias; code as you would for .Net framework:

extern alias ExampleAlias;

using ExampleAlias::Namespace;

and everything works. Docs for that here

Liam
  • 27,717
  • 28
  • 128
  • 190
0

There is no support for this at the moment. Feel free to file an issue in dotnet cli repo https://github.com/dotnet/cli/issues

Pavel Krymets
  • 6,253
  • 1
  • 22
  • 35
-2

You can do it in this way:

extern alias Lib1;
extern alias Lib2;
using System;
using SpaceOne=Lib1::Space;
using SpaceTwo=Lib2::Space;

Example you can find here: https://github.com/ernado-x/owl/blob/master/src/Owl/Program.cs

  • 1
    While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – Alex Riabov Aug 30 '18 at 22:21
  • 2
    This is missing information on how to setup the alias in the csproj – Isen Ng Jul 23 '19 at 06:18