Developer notes
There are two things that make the R type provider tricky:
When you use R provider via NuGet and the F# compiler references the R provider, it attempts to load it from the location where NuGet puts it. This is typically
packages/RProvider.1.0.8/lib
. This directory does not containRDotNet.dll
(which is installed inpackages/R.NET.1.3.5/lib/net40
) and so the loading could fail.To avoid this, we need to make sure that the assembly that is loaded by the F# compiler (and Visual Studio) does not trigger loading of R.NET immediately - that way, we can setup
AssemblyResolve
event handler and load R.NET assembly from another directory.Connecting to R is not entirely stable and so we do not want to crash the F# compiler (or Visual Studio) when something goes wrong with R. For this reason, we run the type discovery in a separate process and communicate with it via .NET remoting.
Project structure
To solve the two issues outlined above, the project structure looks like this:
Things to keep in mind
Here is what you need to know about individual assemblies in the solution:
RProvider.Runtime.dll
- this is the assembly that contains most of the interesting runtime functionality (such as initialization of R, interop with R and converters that convert values between F# and R). It also contains helpers (logging, etc.).This assembly references R.NET in its public assemblies and so when it is loaded, .NET needs to be able to load R.NET (i.e. the
AssemblyResolve
event handler needs to be set up).RProvider.dll
- this is the assembly that the user of R provider will reference. It does not contain any useful code - it only containsTypeProviderAssembly
attribute pointing to the assembly with the actual type provider code.Note that we cannot put the functionality from
RProvider.Runtime.dll
here, because the code needs to be referenced by the other two assemblies (that are compiled before the type provider can be loaded).RProvider.DesignTime.dll
- this is where the type provider code lives. This sets upAssemblyResolve
event handler and then it generates types (by calling theRProvider.Server.exe
to do the type discovery).RProvider.Server.exe
- this is started as a stand-alone process that performs type and package discovery in R. It is called by the DesignTime component and restarted automatically. This also needs to setup theAssemblyResolve
event handler.