Skip to content
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

Add support for extern alias #513

Open
5 of 6 tasks
cloudRoutine opened this issue Nov 8, 2016 · 8 comments
Open
5 of 6 tasks

Add support for extern alias #513

cloudRoutine opened this issue Nov 8, 2016 · 8 comments

Comments

@cloudRoutine
Copy link

cloudRoutine commented Nov 8, 2016

extern alias C# reference

You might have to reference two versions of assemblies that have the same fully-qualified type names. For example, you might have to use two or more versions of an assembly in the same application. By using an external assembly alias, the namespaces from each assembly can be wrapped inside root-level namespaces named by the alias, which enables them to be used in the same file.

This became an issue for me while working on implementing editor tooling to support the old fsproj format and the new netcore fsproj format. MSBuild15 does not properly parse the old files and MSBuild14 doesn't properly parse the new files. Without support for both the tooling will either lock out legacy projects or it'll be unable to process netcore projects.

Pros

  • An application can or make use of multiple versions of an API or SDK
  • A C# shim project solely for the use of extern alias will no longer be necessary

Cons

  • An additional keyword is needed

Extra informtion

Estimated cost M

Affadavit (must be submitted)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I would be willing to help implement and/or test this
  • I or my company would be willing to help crowdfund F# Software Foundation members to work on this
@Rickasaurus
Copy link

I've rubbed up against this problem as well, in particular with clashing Newtonsoft versions. Would love to see a solution.

@cloudRoutine
Copy link
Author

Once again I've run into a wall while working on VFT because we don't have this :(

@ghost
Copy link

ghost commented Sep 22, 2021

We (the Hedgehog maintainers) are running into this as a potential problem as well. We'd like to reference the last released version of our library to test the next version, but we'd then have two Hedgehog.dll files and two Hedgehog namespaces. This is less than ideal, and we're most likely going to end up with a C# shim or some such to get around this.

@cartermp
Copy link
Member

@adam-becker what about a separate test project with shared files?

@ghost
Copy link

ghost commented Sep 22, 2021

@cartermp How would we pin the files to the latest official release?

To clarify, this is the solution we'd like to see:

<!-- Hedgehog.Tests.fsproj -->
<PackageReference Include="Hedgehog" Version="0.10.0" Alias="Latest" />
<!-- Aliasing either reference would be a solution for us -->
<!-- The project referenced here is vNext (0.11.0 in this case) -->
<ProjectReference Include="..\..\src\Hedgehog\Hedgehog.fsproj" Alias="Current" />

Then in our tests:

open Latest.Hedgehog

testProperty "Can test new code using the previous release" (fun () -> property { // `property` from the `Latest.Hedgehog` package ref
  let gen = Current.Hedgehog.Gen.int32 // ...
  // prove something about the current `Gen` type.
})

We've discussed a few workaround solutions in the referenced issue, but at the end of the day these are all workarounds.

@cartermp
Copy link
Member

I don't think you can. But honestly, if you're looking to validate that both the current release and source all pass, you should just use a separate test project.

Although I'm really not sure what you're trying to accomplish and why this is the solution. Wouldn't this entire strategy fail if you decide to incur a breaking change?

@abelbraaksma
Copy link
Member

abelbraaksma commented Sep 14, 2022

Afaik, the extern alias in C# is meant for two separate assemblies with types that happen to have the same FQN. Maybe it also works if these are essentially slightly different versions of the same assembly. EDIT: yes, that works.

The documentation on extern alias says that you need to explicitly pass it as arguments on the commandline (I assume that's why above the suggestion was made for Alias in the fsproj file) and then use the MyAlias::a.b.c and MyOtherAlias::a.b.c syntax to access these aliased namespaces.

Since we also have the concept of global. in F#, it wouldn't be entirely otherworldly to consider this, I guess. It'd pair nice with the C# feature and you wouldn't have to do complex dynamic loading, or have separate builds.

PS: if you look at our documentation on /r:x.dll or /reference:x.dll, it literally says "see /reference (C# Compiler Options).", which then explains the use of Aliases. And yes, you can add these to your fsproj file, but as far as I can tell, they don't lead to a different name for your namespace in code.

Here's a screenshot from an F# project. Note that F# does nothing with this alias:
image

So, if anything, this should be mentioned in our docs. I.e., that it is not entirely equivalent to the same-named C# option.

@abelbraaksma
Copy link
Member

This may actually benefit the F# compiler itself as well, as (at least theoretically) it would allow a single build to be able to access multiple versions of FSharp.dll, which in turn would allow (through those aliases) creation of tests that showcase particular differences between one and another version.

(whether this is useful at all, I don't know....)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants