I am unable to use a Type Provider on a localhost for an Android Emulator.
This doesn't work for me when using F#'s Type Provider because the TypeProvider establishes a connection at design-time.
The Type Provider is happy when I use localhost
[<Literal>]
let JsonPath = "http://localhost:48213/api/cars"
type Repository = JsonProvider<JsonPath>
However, I receive a connection refused when attempting to use the localhost path. Details about this error can be found here.
As a result, I believe the resolution is to use an alternative IP address:
The Type Provider is NOT happy when I use 10.0.2.2
Replacing "localhost" with "10.0.2.2" on the IP address results in a compilation error stemming from the TypeProvider not establishing a connection to the updated IP address.
The following code will not compile when I attempt to use "10.0.2.2" as the alternative IP (AKA: workaround) which is the required IP for the emulator to work:
[<Literal>] (* "10.0.2.2" is the workaround IP for local host *)
let JsonPath = "http://10.0.2.2:48213/api/cars"
type Repository = JsonProvider<JsonPath>
type Car = { Make:string ; Model:string }
let getCars() =
Repository.Load JsonPath
|> Array.toSeq
|> Seq.map(fun x -> { Make=x.Make ; Model=x.Model })
In conclusion, how can I access a file via a WebAPI service run locally, and still keep the Type Provider happy when executing the Type Provider on an Emulator?
The static parameter you provide when you create the JsonProvider
is purely for design time, in order for it to generate you the types. When you call Repositor.Load
this will be the uri you use for runtime. They should be treated separately, like this:
[<Literal>]
let DevelopmentJsonPath = "http://localhost:48213/api/cars"
type Repository = JsonProvider<DevelopmentJsonPath>
type Car = { Make:string ; Model:string }
let runtimeUri = "http://production.mycompany.com/api/cars"
let getCars() =
Repository.Load runtimeUri
|> Array.toSeq
|> Seq.map(fun x -> { Make=x.Make ; Model=x.Model })