fslaborg / RProvider

Access R packages from F#
http://fslab.org/RProvider/
Other
235 stars 69 forks source link

Loading RProvider + Deedle.RPlugin at compiler-time fails when multiple version of Deedle packages exist #118

Closed hmansell closed 10 years ago

hmansell commented 10 years ago

Today we updated our internal projects to use Deedle v1.0.2. They were previously using Deedle v1.0.1. To our surprise, we got a problem loading the RProvider at compile time.

The error was: 2>parse error FS3053: error : The type provider constructor has thrown an exception: Could not load file or assembly 'Deedle, Version=1.0.2.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

Process Explorer showed that the RProvider.Server.exe had Deedle v1.0.1 loaded, which was unexpected.

hmansell commented 10 years ago

The cause was determined to be the existence of the Deedle.1.0.1 directory under packages, in addition to Deedle.1.0.2. If we manually remove it, the error goes away.

Turns out this is a problem in the resolveReferencedAssembly function in Configuration.fs. With the included config file, this finds all Deedle dlls in your packages directory, then loads them in turn using Assembly.LoadFrom, and if the version matches, it resolves to that assembly. Problem is, Assembly.LoadFrom cannot load more than one version of the same assembly. Subsequent attempts to load a different version just return the first version that was loaded. Therefore, if it loads Deedle.1.0.1 first, and the assembly resolve request is for Deedle.1.0.2 (which Deedle.RPlugin v1.0.2 needs), it will not successfully load Deedle.

The fix uses ReflectionOnlyLoad to load each candidate assembly and inspect its version, only calling Assembly.LoadFrom on the correct assembly.

Fix is in #117.