从TypeProvider引用Newtonsoft.Json

时间:2014-06-04 15:03:53

标签: f# json.net type-providers

我正在尝试使用Newtonsoft.Json创建Type Provider。提供的构造函数接受JObject

let constr = ProvidedConstructor([ProvidedParameter("json",typeof<JObject>)])  
constr.InvokeCode <- fun args -> 
    <@@
        let jObject = %%args.[0]:JObject
        jObject
    @@>

客户代码:

type ProvidedType = MyProvider<"source.file">
let json = JObject.Parse(str)
let objct = ProvidedType("""{ "name" = "foo bar" }""")

设计时失败,出现以下错误:

Type mismatch when splicing expression into quotation literal. The type of the
expression tree being inserted doesn't match the type expected by the splicing
operation. 
Expected 'Newtonsoft.Json.Linq.JObject', but received type 
'Newtonsoft.Json.Linq.JObject'. 
Consider type-annotating with the expected expression type, e.g., 
(%% x : string) or (%x : string).

调试类型提供程序时,我可以看到有两个版本的Newtonsoft.Json.dll:版本6.0.3.17227来自我的项目中的nuget下载位置和版本4.5.11.15520来自C:\ Program Files \ Common Files \ Microsoft Shared \ Visual Studio \ 12.0 \ Newtonsoft.Json.dll。

显然,后者显然由Visual Studio 2013 Update 2为Json编辑器加载。

客户端和类型提供程序程序集都指定版本重定向:

<dependentAssembly>
   <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
   <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.3.0" />
</dependentAssembly>

我该如何解决这个问题?

编辑:

事实证明,摆脱VS版本的Json.NET并不是一个好的解决方案。在您尝试使用其他帐户登录之前,VS会在启动时抛出异常。我甚至不想尝试猜测它背后的逻辑,简短的回答是 - 不要与VS混淆。

对于Type Provider,解决方法是在所有TP提供的方法中用一个字符串替换JObject,并在实现中将其解析为JObject。

让我们希望VS团队能为此做点什么。

1 个答案:

答案 0 :(得分:3)

检查Visual Studio目录中的NewtonSoft.Json是否确实存在。我曾经尝试过一次开发类型提供程序时遇到了惊人的痛苦,直到我意识到3个月前的几天NuGet已经将我安装的所有内容的所有依赖项解压缩到C:\ Program Files \ Common Files \ Microsoft Shared \ Visual Studio \ 12.0 \ - 以及在类型提供程序加载任何内容之前加载的那些。作为(非常小的)安慰奖,如果你遇到与我相同的问题,TP将在FSI /编译代码中运行 - 而不是在Visual Studio中。