diff --git a/RFCs/FS-1027-fsi-references.md b/RFCs/FS-1027-fsi-references.md index 1a510dfa..9fa0406d 100644 --- a/RFCs/FS-1027-fsi-references.md +++ b/RFCs/FS-1027-fsi-references.md @@ -16,7 +16,7 @@ a) built-in: * `#r "impl: "` * `#r "ref: "` -b) via .dll extension; +b) via .dll extension (see Handler resolution); * `#r "[dependency manager]: "` like * `#r "paket: "` @@ -114,8 +114,8 @@ Behavior should not be so different at runtime. When executing code interactive When launching FSI with a script using one of the new `#r` references, FSI will do the following: -1. Check which tools is registered for a given #r prefix. Error out if no tool can't be found. -2. Let the tool check if each dependency exists in the known place for the specified tool or otherwise the the tool resolve all dependencies. +1. Check which tools is registered for a given #r prefix. Error out if no tool can be found. +2. Let the tool check if each dependency exists in the known place for the specified tool or otherwise the tool resolve all dependencies. 3. `#r` the resolved dependencies in an ephemeral script (or the script generated by Paket if using Paket). 4. `#load` that script into the FSI session, thus giving it the references it needs to execute. @@ -123,7 +123,7 @@ When launching FSI with a script using one of the new `#r` references, FSI will This scenario is as follows: I have launched FSI at some point, and now I wish to execute a script which may or may not have references that I already have loaded into FSI. The behavior should actually be the same as if FSI were launched with the script: -1. Check which tools is registered for a given #r prefix. Error out if no tool can't be found. +1. Check which tools is registered for a given #r prefix. Error out if no tool can be found. 2. Call out to the tool to resolve dependencies. 3. `#r` the resolved dependencies in an ephemeral script (or the script generated by Paket if using Paket). Check version numbers against what we already have loaded in the FSI session. If any `.dll` names and versions match, don't `#r` them into the script. 4. `#load` that script into the FSI session, thus giving it the references it needs to execute. @@ -162,6 +162,18 @@ This will generate an error because `System.Whatever` version `4.1.0` will alrea We may consider using `AssemblyLoadContext` in some clever way in the future, but it's very difficult to get right and well outside the scope of what we need to support for a .NET Core 2.0 timeframe. +## Handler resolution + +FSI/Design time support will look at the following places in order: + +* if the script is a physical file, check current folder and browse all parent folders looking for .fsharp/fsi-extensions folder in each one +* look into ~/.fsharp/fsi-extensions +* look into .fsharp/fsi-extensions folder next to fsi.exe + +gather all the distinct dll names, order of precedence favorising those in the same order shown above, and load them in the process if their assembly contains an arbitrary attribute (resolved by name rather than dependency on external library) and types marked with same attributes. + +If a handler key (such as `nuget` or `paket`) is found several times, report a warning showing location of assemblies and showing which one was picked (we apply same order of precedence as for finding the assemblies). + # Drawbacks [drawbacks]: #drawbacks