TypeProvider 无法从 Expression 添加方法
TypeProvider failed to add method from Expression
我使用 .net 核心模板创建了一个空白类型提供程序 dotnet new typeprovider -n LemonadeProvider -lang F#
。项目构建,但是当我想更改提供方法以在表达式中调用另一个类似的方法时:
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ allEntities () @@>))
myType.AddMember(meth)
我尝试通过以下代码进行测试:
type Connection = LemonadeProvider.GenerativeProvider<"5">
[<Fact>]
let ``AllEntities simply works`` () =
let obj = Connection()
Assert.true(obj.AllEntities() = "dd")
我收到以下错误:
LemonadeProvider.Tests.fs(20,19): error FS3033: TypeProvider "LemonadeProviderImplementation+BasicGenerativeProvider" reports an error:: The design-time type 'LemonadeProviderImplementation+allEntities@96' utilized by a type provider was not found in the target reference assembly set '[tgt assembly Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly WitAi.Runtime, Version=1.0.0.0, Culture=neutral; tgt assembly xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.execution.desktop, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly System.ComponentModel.Annotations, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ComponentModel.EventBasedAsync, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Contracts, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Dynamic.Runtime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.NetworkInformation, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.InteropServices.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Primitives, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Xml, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Duplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Http, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.NetTcp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.XmlSerializer, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly FSharp.Core, Version=4.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Collections.Concurrent, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Collections, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Debug, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Tools, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Tracing, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Globalization, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.IO, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Expressions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Queryable, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.Primitives, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.Requests, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.WebHeaderCollection, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ObjectModel, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit.Lightweight, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Resources.ResourceManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Extensions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Handles, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.InteropServices, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Security.Principal, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.Encoding, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.Encoding.Extensions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.RegularExpressions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Tasks, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Tasks.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Timer, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.ReaderWriter, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.XDocument, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tmp5A6]'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using. [C:\git\LemonadeProvider.Tests.fsproj]
当 ProvideMethod
只是 return const 值时,一切看起来都很好,我没有收到错误:
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ ("dd") @@>))
myType.AddMember(meth)
提供商的整个代码如下所示:
[<TypeProvider>]
type BasicGenerativeProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces (config, assemblyReplacementMap=[("LemonadeProvider.DesignTime", "LemonadeProvider.Runtime")])
let ns = "LemonadeProvider"
let asm = Assembly.GetExecutingAssembly()
// check we contain a copy of runtime files, and are not referencing the runtime DLL
do assert (typeof<DataSource>.Assembly.GetName().Name = asm.GetName().Name)
let createType typeName (auth: string, version: string) =
let asm = ProvidedAssembly()
let myType = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>, isErased=false)
let ctor = ProvidedConstructor([], invokeCode = fun args -> <@@ "My internal state" :> obj @@>)
myType.AddMember(ctor)
let ctor2 = ProvidedConstructor([ProvidedParameter("InnerState", typeof<string>)], invokeCode = fun args -> <@@ (%%(args.[1]):string) :> obj @@>)
myType.AddMember(ctor2)
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string []>, invokeCode = (fun _ -> <@@ allEntities () @@>))
myType.AddMember(meth)
asm.AddTypes [ myType ]
myType
let myParamType =
let t = ProvidedTypeDefinition(asm, ns, "GenerativeProvider", Some typeof<obj>, isErased=false)
t.DefineStaticParameters( [ProvidedStaticParameter("AuthToken", typeof<string>)], fun typeName args -> createType typeName ("token", "version"))
t
do
this.AddNamespace(ns, [myParamType])
我的观察:
编译测试时,LemonadeProvider.DesignTime dll 参与 fsc 管道(在实际编译之前)以根据您提供的 createType 定义生成类型。
类型是在单独的程序集(似乎是匿名的)中从 LemonadeProvider.DesignTime 生成的,它与 LemonadeProvider.Runtime.dll 一起包含在测试源的实际编译过程中。请注意,LemonadeProvider.DesignTime 似乎不再包含在此步骤中。首先我以为 LemonadeProvider.Runtime.dll 包含生成的类型,但在 ilspy 中检查后我没有找到任何。
LemonadeProvider.DesignTime 未包含在实际源代码编译中。这意味着此处定义的任何类型(如模块助手的定义)将不可用。但是当你写:let allEntities() = "dd"
- 这会在 LemonadeProvider.DesignTime 中生成一个 class。在我的例子中是:
但是这个class是not reachable
- 行:
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ allEntities() @@>))
引用形式 AST 类似于:
- 请注意,类型是在 AST 中捕获的。因此,当引用的反序列化发生在没有 DesignTime.dll 的上下文中时,您会看到编译错误。
- 代码:
let allEntities = "dd"
let allEntitiesQuote = <@@ allEntities @@>
我们有下一个 AST:ValueWithName ("dd", allEntities) - 所以没有对类型的引用。
- 要在引号内包含函数 - 使用 DataSource class。它也在 Runtime dll 中定义,因此会找到相应的生成函数类型。
在 Runtime.fsproj Runtime.fs:
type DataSource(filename:string) =
member this.FileName = filename
static member allEntities() = "dd"
这对我有用。您也可以在 Utilities 模块中使用 allEntities,但删除 internal 关键字。
- 如果您仍想在 DesignTime dll 中定义函数,我假设您需要以引用的形式组织它并为其提供 Provided* 方法。
我使用 .net 核心模板创建了一个空白类型提供程序 dotnet new typeprovider -n LemonadeProvider -lang F#
。项目构建,但是当我想更改提供方法以在表达式中调用另一个类似的方法时:
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ allEntities () @@>))
myType.AddMember(meth)
我尝试通过以下代码进行测试:
type Connection = LemonadeProvider.GenerativeProvider<"5">
[<Fact>]
let ``AllEntities simply works`` () =
let obj = Connection()
Assert.true(obj.AllEntities() = "dd")
我收到以下错误:
LemonadeProvider.Tests.fs(20,19): error FS3033: TypeProvider "LemonadeProviderImplementation+BasicGenerativeProvider" reports an error:: The design-time type 'LemonadeProviderImplementation+allEntities@96' utilized by a type provider was not found in the target reference assembly set '[tgt assembly Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly WitAi.Runtime, Version=1.0.0.0, Culture=neutral; tgt assembly xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly xunit.execution.desktop, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c; tgt assembly System.ComponentModel.Annotations, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ComponentModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ComponentModel.EventBasedAsync, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Contracts, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Dynamic.Runtime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.NetworkInformation, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.InteropServices.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Primitives, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Serialization.Xml, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Duplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Http, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.NetTcp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ServiceModel.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.XmlSerializer, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly FSharp.Core, Version=4.4.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089; tgt assembly System.Collections.Concurrent, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Collections, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Debug, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Tools, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Diagnostics.Tracing, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Globalization, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.IO, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Expressions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Linq.Queryable, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.Primitives, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.Requests, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Net.WebHeaderCollection, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.ObjectModel, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit.ILGeneration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Emit.Lightweight, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Reflection.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Resources.ResourceManager, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Extensions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Handles, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.InteropServices, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Runtime.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Security.Principal, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.Encoding, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.Encoding.Extensions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Text.RegularExpressions, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Tasks, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Tasks.Parallel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Threading.Timer, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.ReaderWriter, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tgt assembly System.Xml.XDocument, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; tmp5A6]'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using. [C:\git\LemonadeProvider.Tests.fsproj]
当 ProvideMethod
只是 return const 值时,一切看起来都很好,我没有收到错误:
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ ("dd") @@>))
myType.AddMember(meth)
提供商的整个代码如下所示:
[<TypeProvider>]
type BasicGenerativeProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces (config, assemblyReplacementMap=[("LemonadeProvider.DesignTime", "LemonadeProvider.Runtime")])
let ns = "LemonadeProvider"
let asm = Assembly.GetExecutingAssembly()
// check we contain a copy of runtime files, and are not referencing the runtime DLL
do assert (typeof<DataSource>.Assembly.GetName().Name = asm.GetName().Name)
let createType typeName (auth: string, version: string) =
let asm = ProvidedAssembly()
let myType = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>, isErased=false)
let ctor = ProvidedConstructor([], invokeCode = fun args -> <@@ "My internal state" :> obj @@>)
myType.AddMember(ctor)
let ctor2 = ProvidedConstructor([ProvidedParameter("InnerState", typeof<string>)], invokeCode = fun args -> <@@ (%%(args.[1]):string) :> obj @@>)
myType.AddMember(ctor2)
let allEntities () = "dd"
let meth = ProvidedMethod("AllEntities", [], typeof<string []>, invokeCode = (fun _ -> <@@ allEntities () @@>))
myType.AddMember(meth)
asm.AddTypes [ myType ]
myType
let myParamType =
let t = ProvidedTypeDefinition(asm, ns, "GenerativeProvider", Some typeof<obj>, isErased=false)
t.DefineStaticParameters( [ProvidedStaticParameter("AuthToken", typeof<string>)], fun typeName args -> createType typeName ("token", "version"))
t
do
this.AddNamespace(ns, [myParamType])
我的观察:
编译测试时,LemonadeProvider.DesignTime dll 参与 fsc 管道(在实际编译之前)以根据您提供的 createType 定义生成类型。
类型是在单独的程序集(似乎是匿名的)中从 LemonadeProvider.DesignTime 生成的,它与 LemonadeProvider.Runtime.dll 一起包含在测试源的实际编译过程中。请注意,LemonadeProvider.DesignTime 似乎不再包含在此步骤中。首先我以为 LemonadeProvider.Runtime.dll 包含生成的类型,但在 ilspy 中检查后我没有找到任何。
LemonadeProvider.DesignTime 未包含在实际源代码编译中。这意味着此处定义的任何类型(如模块助手的定义)将不可用。但是当你写:
let allEntities() = "dd"
- 这会在 LemonadeProvider.DesignTime 中生成一个 class。在我的例子中是:
但是这个class是not reachable
- 行:
let meth = ProvidedMethod("AllEntities", [], typeof<string>, invokeCode = (fun _ -> <@@ allEntities() @@>))
引用形式 AST 类似于:
- 代码:
let allEntities = "dd"
let allEntitiesQuote = <@@ allEntities @@>
我们有下一个 AST:ValueWithName ("dd", allEntities) - 所以没有对类型的引用。
- 要在引号内包含函数 - 使用 DataSource class。它也在 Runtime dll 中定义,因此会找到相应的生成函数类型。 在 Runtime.fsproj Runtime.fs:
type DataSource(filename:string) =
member this.FileName = filename
static member allEntities() = "dd"
这对我有用。您也可以在 Utilities 模块中使用 allEntities,但删除 internal 关键字。
- 如果您仍想在 DesignTime dll 中定义函数,我假设您需要以引用的形式组织它并为其提供 Provided* 方法。