You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
dotnet new typeprovider -n LemonadeProvider -lang F#
17
-
18
-
The template uses paket to acquire the files of the latest published type provider SDK.
19
-
20
-
cd LemonadeProvider
21
-
22
-
dotnet tool restore
23
-
dotnet paket update
24
-
dotnet build -c release
25
-
26
-
dotnet test -c release
27
-
28
-
The type provider also contains the logic necessary to package the type provider:
29
-
30
-
dotnet paket pack nuget --version 0.0.1
31
-
32
-
## The ProvidedTypes API - A Basic Type Provider
33
-
34
-
When you instantiate the template above you get basic erasing and generative type providers.
35
-
36
-
## Some unit testing helpers
37
-
38
-
The SDK includes a file
39
-
40
-
* ProvidedTypesTesting.fs
41
-
42
-
which is sometimes incorporated into a type provider to help enable unit testing. For examples of how this is used, see uses of the helpers in the FSharp.Data library such as:
*``Targets.DotNetStandard20FSharpRefs`` to get a suitable set of references for .NET Standard plus the running FSharp.Core
46
-
*[``Testing.FormatProvidedType``](https://github.com/fsharp/FSharp.Data/blob/f5df4554938138c60af2ec886d5a132883633351/src/TypeProviderInstantiation.fs#L171) to get a textual representation of a provided type, used to "snapshot" the full description of expected type generation
47
-
48
-
Sometimes unit test DLLs incorporate the entire type provider implementation, and sometimes they use InternalsVisibleTo.
49
-
50
-
The unit testing helpers aren't really an official, documented part of the SDK - caveat emptor.
51
-
52
-
## Examples
53
-
54
-
See examples the [`examples`](examples) directory.
55
-
56
-
## Type Provider Naming Conventions
57
-
58
-
A type provider is simultaneously a tool and a library. The existing guidance is as follows, from https://fsharp.github.io/2014/09/19/fsharp-libraries.html.
59
-
60
-
> Likewise, a type provider for a data source or schema format XYZ should normally be placed in “FSharp.Data”, e.g. “FSharp.Data.XYZ”.
61
-
62
-
Good type provider naming examples:
63
-
64
-
*`FSharp.Text.RegexProvider`
65
-
*`FSharp.Azure.StorageTypeProvider`
66
-
67
-
Existing type providers that don't quite follow the guidelines but which are ok:
68
-
69
-
*`FSharp.Data`
70
-
71
-
Here are some examples of existing type providers that aren't too bad (they are clear) but could be renamed to follow the guidelines:
72
-
73
-
*`ExcelProvider` (better would be `FSharp.Interop.ExcelProvider`)
74
-
*`RProvider` (better would be `FSharp.Interop.RProvider`)
75
-
*`ApiaryProvider` (better would be `FSharp.Data.ApiaryProvider`)
76
-
*`SQLProvider` (better would be `FSharp.Data.SQLProvider`)
77
-
*`DynamicsNAVProvider` (better would be `FSharp.Interop.DynamicsNAVProvider`)
78
-
*`DynamicsCRMProvider` (better would be `FSharp.Interop.DynamicsCRMProvider`)
79
-
80
-
## Technical Notes
81
-
82
-
### Using Type Providers with ``dotnet build``
83
-
84
-
Correctly updated type providers can be used with either the `dotnet` toolchain (.NET SDK tools which executes using .NET Core) or `msbuild` (traditional .NET Framework/Mono) toolchain.
85
-
86
-
### Nuget package layouts you should use
87
-
88
-
The typical nuget package layout for a very simple provider that has **combined** design-time and runtime components and **no dependencies** is:
89
-
90
-
lib/netstandard2.0
91
-
MyProvider.dll // acts as both TPRTC and TPDTC
92
-
93
-
The typical nuget package layout for a provider that has separate design-time and runtime components is like this. You should also likely use this if your type provider has any extra dependencies.
94
-
95
-
lib/netstandard2.0
96
-
MyProvider.dll // TPRTC
97
-
98
-
typeproviders/fsharp41/
99
-
netstandard2.0/
100
-
MyProvider.DesignTime.dll // TPDTC
101
-
MyDesignTimeDependency.dll // bundled dependencies of TPDTC
102
-
103
-
Runtime dependencies are often the same as design time dependencies for simple type providers. For more complex providers these can be different
104
-
105
-
* The runtime dependencies are the dependencies of everything in your quotations in your type provider implementation.
106
-
107
-
* The design dependencies are the dependencies of everything outside the quotations to decide and generate the provided types.
108
-
109
-
These dependencies are packaged and managed differently
110
-
111
-
* The runtime dependencies are normal nuget package dependencies just like any normal .NET library. For example, if your type provider has Newtonsoft.Json as a runtime
112
-
dependency then your nuget package should list this a normal nuget dependency.
113
-
114
-
* The design dependencies must all be bundled alongside your design-time DLL. The design-time component is a component loaded into a tool like Ionide or
115
-
Visual Studio and must be loadable without referencing any other packages.
116
-
117
-
118
-
### Lifetime of type provider instantiations
119
-
120
-
F# type providers are hosted by applications using FSharp.Compiler.Service.
121
-
These notes describe the lifetime and typical resource usage of type provider instances for applications that incorporate
122
-
FSharp.Compiler.Service (the host). Most documentation on the compiler as a service can be found at http://github.com/fsharp/FSharp.Compiler.Service.
123
-
124
-
Each time the host application (e.g. devenv.exe) checks a file using type providers (e.g. containing `JsonProvider<"...">`), one or more new TP instantiations may be created, along with subsequent calls to `ApplyStaticArguments`.
125
-
126
-
* The F# compiler service doesn't try to cache these (except where it caches the TAST structures that results of checking a file or project).
127
-
128
-
* Individual type providers may use caching of some kind, returning previous provided types when the type provider is instantiated the same way. Care should be taken that these caches do not permanently occupy resources
129
-
130
-
* Under the hood, the majority of resources used by a TP instantiation are those required to "map" the generated types to the referenced assemblies. To support this, each TP Instantiation creates one ILModuleReader for each referenced assembly. When the compiler is used as a service, the natural (minimal) lifetime of a ILModuleReader is the same as its TP Instanatiation. The TPSDK may share these resources.
131
-
132
-
* The natural (i.e. minimal) lifetime of a TP Instantiation and its related objects (ProvidedType ProvidedMethodInfo etc. etc. ) is the same as the TAST structures which refer these things (TProvidedTypeInfo, MethInfo, FieldInfo from infos.fs).
133
-
134
-
The lifetime of TAST structures is as long as they are held in the IncrementalBuilder, or you hold on to FSharpCheckFileResults, or FSharpCheckProjectResults, or FSharpAssemblyContents.
135
-
136
-
### FAQ
137
-
138
-
#### How do I debug execution of a type provider when using .NET Framework tools on Windows?
139
-
140
-
1. Capture output of `msbuild -v:n` in `args.txt` and trim out the rubbish leaving just the command line arguments to the F# compiler, usually starting with `-o:...`
141
-
142
-
2. Run an explicit invocation of the compiler using this, checking that your failures still happen
143
-
144
-
fsc.exe @args.txt
145
-
146
-
Then debug that invocation using
147
-
148
-
devenv /debugexe fsc.exe @args.txt
149
-
150
-
If your failures only happen in the IDE then use `devenv /debugexe devenv.exe MyProj.fsproj`, set debug type to ".NET Framework 4.0" and launch F5. Likewise if your failures only happen in F# Interactive then use `devenv /debugexe fsi.exe MyProj.fsproj`.
151
-
152
-
Set first-catch exception handling (Ctrl-Alt-E, select all CLR exceptions) and set Just My Code off
153
-
154
-
#### A dependency of my type provider is not loading, what do I do?
155
-
156
-
For example, let's say you have this error in your test project:
157
-
158
-
```
159
-
2>E:\GitHub\admin\joe-provider\test\Joe.Test\ProviderTests.fs(8,10): error FS3033: The type provider 'Joe.Provider.JoeProvider' reported an error: Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified. [E:\GitHub\dsyme\joe-provider\test\Joe.Test\Joe.Test.fsproj]
160
-
```
161
-
162
-
Here your test project is referencing your provider project, and your type provider has a dependency on `Newtonsoft.Json.dll`. To see what's going on, run
163
-
164
-
dotnet build -v:n
165
-
166
-
In the compilation of your test project you will see something like this:
will include the component and unblock you. However, you will need to be careful to make sure this component is laid down in the right place in your nuget
180
-
package, see the instructions above for what the final layout of the nuget package should be.
181
-
182
-
2. When making type providers whose design-time components have dependencies, you should always use a "split" type provider that separates the design-time and runtime components.
183
-
184
-
TODO: give exact .fsproj/nuget instructions to get the dependency into the `typeproviders\fsharp41\netstandard2.0` directory alongside the design-time component.
185
-
186
-
#### How do I debug execution of a type provider when using .NET Core tools on Windows?
187
-
188
-
One approach:
189
-
190
-
1. Capture output of `dotnet build -v:n` in `args.txt` and trim out the rubbish leaving just the command line arguments to the F# compiler, usually starting with `-o:...`
191
-
192
-
2. Run an explicit invocation of the compiler using:
Be careful to make sure Visual Studio debugging type is set to ".NET Core" (right click properties on dotnet and set debug type)
201
-
202
-
Set first-catch exception handling (Ctrl-Alt-E, select all CLR exceptions) and set Just My Code off.
203
-
204
-
### Some Type Provider terminology
205
-
206
-
* TPRTC - Type Provider Run Time Component, e.g. ``FSharp.Data.dll``.
207
-
208
-
* This is the component referenced by ``#r`` or ``-r:`` on the command line or other configration of a host tool
209
-
210
-
* May be the same physical file as the TPDTC.
211
-
212
-
* Contains either a [``TypeProviderAssembly()``](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/compilerservices.typeproviderassemblyattribute-class-%5Bfsharp%5D) attribute indicating that this component is also a TPDTC, or ``TypeProviderAssembly("MyDesignTime.dll")`` attribute indicating that the name of the design time component.
213
-
214
-
* A type provider package may have multiple such DLLs for different target platforms, e.g.
215
-
216
-
lib\net45\FSharp.Data.dll
217
-
lib\netstandard2.0\FSharp.Data.dll
218
-
219
-
* TPRTCs are normally .NET Framework 4.x, .NET Standard 2.0 or some portable profile component.
220
-
221
-
* TPDTC - Type Provider Design Time Component, e.g. ``FSharp.Data.DesignTime.dll``.
222
-
223
-
* The DLL that gets loaded into host tools.
224
-
225
-
* May be the same physical file as the TPRTC.
226
-
227
-
* This component includes the ProvidedTypes.fs/fsi files from the type provider SDK.
228
-
229
-
* TPDTCs are currently .NET Framework 4.x. They can also be .NET Standard 2.0 components, see below
230
-
231
-
* Host tool - Either ``fsc.exe``, ``fsi.exe`` or some tool hosting ``FSharp.Compiler.Service.dll`` such as ``devenv.exe`` or ``FsAutoComplete.exe``
232
-
233
-
### How the TPDTC is found and loaded
234
-
235
-
Currently, host tools look for TPDTC DLLs alongside the TPRTC DLL. For simple type providers, these DLLs are the same. When executing using .NET Framework, the host tool uses ``Assembly.LoadFrom`` to load this component.
236
-
237
-
See [Type provider design-time DLLs should be chosen more appropriately](https://github.com/Microsoft/visualfsharp/issues/3736) for a proposal to change the rules to allow TPDTC components to be found more usefully, and in particular for different TPDTC components to be loaded depending on the execution environment of the host tooling.
238
-
239
-
### Explicit construction of code: MakeGenericType, MakeGenericMethod and UncheckedQuotations
240
-
241
-
Some type providers need to build code via explicit calls to `FSharp.Quotations.Expr.*` rather than via quotation
242
-
literals. Frequently, this is needed when code must instantiate generic methods or types. However, in some cases limitations
243
-
of the F# quotations API are reached.
244
-
245
-
In these cases, follow these rules
246
-
247
-
1. Always use `ProvidedTypeBuilder.MakeGenericType(type, typeArguments)` rather than `type.MakeGenericType(typeArguments)`
248
-
1. Always use `ProvidedTypeBuilder.MakeGenericMethod(methInfo, methTypeArguments)` rather than `methInfo.MakeGenericType(methTypeArguments)`
249
-
1. Where necessary open `open ProviderImplementation.ProvidedTypes.UncheckedQuotations` and make quotation nodes representing calls and other operations using `Expr.CallUnchecked`.
250
-
251
-
If you don't do this you may get errors like
252
-
253
-
The type provider 'FSharp.Configuration.ConfigTypeProvider+FSharpConfigurationProvider' reported an error: Type mismatch when building 'args': invalid parameter for a method or indexer property. Expected 'System.Collections.Generic.IEnumerable`1[System.String]', but received type 'System.Collections.Generic.IEnumerable`1[System.String]'.�Parameter name: receivedType
254
-
255
-
or
256
-
257
-
System.InvalidOperationException: the operation is not valid due to the current state of the object. at System.Reflection.MemberInfo.get_MetadataToken() in f:\dd\ndp\clr\src\BCL\system\reflection\memberinfo.cs:line 65
258
-
259
-
## Resources
260
-
261
-
For advice on how to get started building a type provider, check out:
262
-
263
-
-[Type Providers from the ground up](http://blog.mavnn.co.uk/type-providers-from-the-ground-up/)
264
-
- (and the [follow up posts](http://blog.mavnn.co.uk/blog/categories/typeprovider/))
265
-
-[The MSDN Tutorial](http://msdn.microsoft.com/en-us/library/hh361034.aspx). The code in this package replaces the code from the sample pack it mentions.
266
-
13
+
See [the documentation](https://fsprojects.github.io/FSharp.TypeProviders.SDK).
267
14
268
15
## Support and community
269
16
@@ -294,8 +41,6 @@ The library is available under the MIT License. For more information see the [Li
0 commit comments