我希望利用 F# 3.0 类型提供程序机制,基于弱类型数据源生成“强”类型。生成的类型必须可以从只安装了 .Net 4.0 而非 .Net 4.5 的 C# 客户端中访问。如果无法实现 .Net 4.0 兼容性,则我们无法在当前大型 ERP 项目中使用类型提供程序。
到目前为止,我已经成功创建了 MyGeneratedTypes.dll,按照 MSDN 上的 tutorial("Providing Generated Types" 部分)进行操作,使用了“ProvidedTypes-0.2.fs”中的 ProvidedTypeDefinition。 (为了使其工作,我不得不从“ProvidedTypeDefinition.ConvertToGenerated”方法中删除“File.Delete...”行)。
“MyGeneratedTypes.dll”的运行时版本是v4.0.30319,这是可以的(.Net 4.0的运行时)。我可以在C#/.Net 4.0应用程序中添加对“MyGeneratedTypes.dll”的引用,并且智能感知功能会按预期显示类型和成员。但是,当我尝试编译时,C#编译器失败并产生“警告MSB3258:无法解析主引用“MyGeneratedTypes”,因为它具有对.NET Framework程序集“FSharp.Core,Version=4.3.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”的间接依赖项,该程序集具有比当前目标框架中的版本“4.0.0.0”更高的版本“4.3.0.0”。”
使用IL Spy查看后发现,“MyGeneratedTypes.dll”确实包含对FSharp.Core 4.3的引用,尽管此引用完全不必要。到目前为止,我还没有找到防止F#编译器将此引用放入生成的程序集中的方法。(我已经创建了一个纯.Net 4.0 C#程序集,并将其传递给
到目前为止,我已经成功创建了 MyGeneratedTypes.dll,按照 MSDN 上的 tutorial("Providing Generated Types" 部分)进行操作,使用了“ProvidedTypes-0.2.fs”中的 ProvidedTypeDefinition。 (为了使其工作,我不得不从“ProvidedTypeDefinition.ConvertToGenerated”方法中删除“File.Delete...”行)。
“MyGeneratedTypes.dll”的运行时版本是v4.0.30319,这是可以的(.Net 4.0的运行时)。我可以在C#/.Net 4.0应用程序中添加对“MyGeneratedTypes.dll”的引用,并且智能感知功能会按预期显示类型和成员。但是,当我尝试编译时,C#编译器失败并产生“警告MSB3258:无法解析主引用“MyGeneratedTypes”,因为它具有对.NET Framework程序集“FSharp.Core,Version=4.3.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a”的间接依赖项,该程序集具有比当前目标框架中的版本“4.0.0.0”更高的版本“4.3.0.0”。”
使用IL Spy查看后发现,“MyGeneratedTypes.dll”确实包含对FSharp.Core 4.3的引用,尽管此引用完全不必要。到目前为止,我还没有找到防止F#编译器将此引用放入生成的程序集中的方法。(我已经创建了一个纯.Net 4.0 C#程序集,并将其传递给
ProvidedTypeDefinition
的构造函数,但这没有影响)。
有没有人知道如何消除引用,或者这是否只是 F# 3.0 发布候选版的问题,在最终版本中将得到解决。
编辑
与 @Brian 的交谈已经导致了以下问题的“部分”解决方案:您可以通过直接从命令行调用 .Net 4.0 C# 编译器 (csc) 来编译引用 F# 3.0 生成类型的库的“纯 C#/.Net 4.0”客户端,但在 VS 2010 中编译或通过 MSBuild 命令行编译时不起作用。我怀疑这是由以下行为引起的:
- MyGeneratedTypes.dll是使用F#类型提供程序机制在VS 2012中生成的。
- 在生成过程中,自动插入对FSharp.Core 4.3的引用(即使不需要),而没有在依赖项的元数据中指定“SpecificVersion:true”。
- 一个在“.Net 4.5-free”系统上的VS 2010中的C#客户端引用了MyGeneratedTypes.dll。
- 当编译C#客户端时,MSBuild发现了MyGeneratedTypes.dll中间接引用到FSharp.Core 4.3。
- 由于间接引用存在“SpecificVersion:false”,MSBuild发出警告MSB3257,并拒绝将直接引用/r:“MyGeneratedTypes.dll”传递给C#编译器(csc)。(注意:MSBuild警告无法以任何方式被抑制。)
- C#编译器(csc)由MSBuild调用,没有/r:“MyGeneratedTypes.dll”。因此,它无法编译,并发出编译器错误CS0246:“找不到类型或命名空间名称'MyGeneratedTypes'(...)”。
SpecificVersion:true
"的引用,否则我们将无法解决此问题。