Downgrading with Nuget

Recently I had a problem where I had blindly (and stupidly) upgraded one of my packages across an entire solution. Only to find out the version was incompatible with some of my code. Instead of making the required changes to fix the problems, due to time constraints I decided to roll back to the previous version, so I broke out the nuget package manager console.

First we need to get a list of projects that have a reference to the nuget package

 $projects =Get-Project -All | Select @{ Name="ProjectName";Expression={$_.ProjectName}}, @{Name="Has";Expression={Get-Package Newtonsoft.Json -Project $_.Name}} | where { $_.Has -ne 'Newtonsoft.Json 4.5.4' }

Then uninstall the package

$projects | select { Uninstall-Package Newtonsoft.Json -ProjectName $_.ProjectName -Force }

It is worth noting this use of the force switch here. This can be quiet dangerous as it can break other packages (see NuGet Docs)

and finally install the new one.

$projects | select { Install-Package Newtonsoft.Json -Version 4.0.8 -ProjectName $_.ProjectName }
Posted in Development | 9 Comments

AppHarbour and Nuget and F#

While deploying an app to AppHarbour today (which I think is fantastic btw.) I came across some problems so I thought I’d document them.

1. Assembly References
with using NuGet and assembly redirects to newer versions. Basically, I had drawn a NuGet dependency on SignalR 0.4, MVC4 Beta and Json.NET 4.5.3

(Note: The assembly version is actually 4.5.0 you can read more about why the versions aren’t in sync on James Newton-Kings blog here)

This all worked fine on my machine, SignalR was happy with the using Json.NET 4.5.0 version despite it being built against 4.0.7 the problems however came when I tried to deploy to AppHarbour, my build started failing with the following messages.

ResolveAssemblyReferences:
  Unified primary reference "Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed".
      Using this version instead of original version "4.0.7.0" in "D:\temp\zm5ue1lf.ozz\input\packages\SignalR.Server.0.4.0.0\lib\net40\SignalR.dll" because AutoUnify is 'true'.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(1360,9): warning MSB3245: Could not resolve this reference. Could not locate the assembly "Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. 

It turns out that NuGet doesn’t seems to always add HintPath property to the Reference node in the project file; I have to admit that this only seems to be a problem with F# I haven’t had to do this with any C# projects yet. To fix this simply add the hint path to point to the correct path.

To do this, unload the project file and right click, and select ‘Edit project file’ then change each of the problematic references as follows

Before:

<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
      <Private>True</Private>
    </Reference>

After:

<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
<HintPath>..\packages\Newtonsoft.Json.4.5.3\lib\net40\Newtonsoft.Json.dll</HintPath>
      <Private>True</Private>
    </Reference>

2. F# 3.0 isn’t on AppHarbour

O.K I already knew this, but I have been developing this app in the visual studio 11 beta. When you create an F# project in VS11 it targets the F# 3.0 MSBuild targets file.

To fix this edit the desired project file, and find the following line

<Import Project="$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets" Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')" />

after this line add the following

  <Import Project="$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets'))" />
  <Import Project="$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets" Condition="(!Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')) And (!Exists('$(MSBuildExtensionsPath32)\..\Microsoft F#\v4.0\Microsoft.FSharp.Targets')) And (Exists('$(MSBuildExtensionsPath32)\FSharp\1.0\Microsoft.FSharp.Targets'))" />

Hope this helps!!

Posted in Development | Tagged , , , | 1 Comment

Union Type serialization with JSON.net

Recently, I have been working with JSON.NET along with F#, and was surprised when it couldn’t (de)serialize union data types. After some googling I realized that I wasn’t the first to come across this and indeed Robert Pickering had a solution which the following code is based on.

open System
open System.Linq
open System.Linq.Expressions
open Newtonsoft.Json
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations

type UnionTypeConverter() =
    inherit JsonConverter()

    let doRead (reader: JsonReader) = 
        reader.Read() |> ignore

    override x.CanConvert(typ:Type) =
        let result = 
            ((typ.GetInterface(typeof<System.Collections.IEnumerable>.FullName) = null) 
            && FSharpType.IsUnion typ)
        result

    override x.WriteJson(writer: JsonWriter, value: obj, serializer: JsonSerializer) =
        let t = value.GetType()
        let write (name : string) (fields : obj []) = 
            writer.WriteStartObject()
            writer.WritePropertyName("case")
            writer.WriteValue(name)  
            writer.WritePropertyName("values")
            serializer.Serialize(writer, fields)
            writer.WriteEndObject()   

        let (info, fields) = FSharpValue.GetUnionFields(value, t)
        write info.Name fields

    override x.ReadJson(reader: JsonReader, objectType: Type, existingValue: obj, serializer: JsonSerializer) =      
         let cases = FSharpType.GetUnionCases(objectType)
         if reader.TokenType <> JsonToken.Null  
         then 
            doRead reader
            doRead reader
            let case = cases |> Array.find(fun x -> x.Name = if reader.Value = null then "None" else reader.Value.ToString())
            doRead reader
            doRead reader
            doRead reader
            let fields =  [| 
                   for field in case.GetFields() do
                       let result = serializer.Deserialize(reader, field.PropertyType)
                       reader.Read() |> ignore
                       yield result
             |] 
            let result = FSharpValue.MakeUnion(case, fields)
            while reader.TokenType <> JsonToken.EndObject do
                doRead reader         
            result
         else
            FSharpValue.MakeUnion(cases.[0], [||]) 
Posted in Development | Tagged , | Leave a comment

Raven Db with F# (FSharpEnt.RavenDB)

 

Update: This is now the F# raven client, distributed as part of the raven db tool chain

Raven DB is a Document database from Ayende (Hibernating Rhinos). The API is nice and clean and a dream to use to C#. However, although the api is functional (i.e. modelled on linq) it is not very nice to use from F#. This is mainly due to the heavy use of Linq.Expressions, and the lack of support for implicit conversion between functions and expressions. (I guess this may change in F# 3.0 as linq queries become more embedded into the language in the form of query expressions)

Getting Started
The wrapper is available on nuget. To install simply enter the following command into the Nuget package manager console.

Install-Package FSharpEnt.RavenDB

This should then download the dependencies and off you go, the library only has a dependency on the RavenDB.Client library, so it does not get the Embedded or Standalone servers that Raven offers, if you don’t have a Document store instance already running you can follow the instructions here to get started with Raven.

Once you have a server up and running, time to set up the application.

Usage

The application can be initialised via passing in a preconfigured document store or using a connection string from the web config

//Embedded Document store
let docStore = (new EmbeddableDocumentStore(RunInMemory = true)).Initialize()
Raven.initWithDocumentStore "myStore" docStore

//From connections string
Raven.initWithConnectionString "myStore" "myConnectionStringFromAppConfig"

once the store has been initialised we can begin to use raven to execute queries and store data. Using this we can initialise many stores pointing to various different databases if needed, and pick out the desired store at run time.

To store data into a the ‘myStore’ instance of raven

let customer = Customer.Create("Test", (new DateTime(2012, 1, 1)))
let stored = withSession "myStore" (store customer)

or using the workflow expression syntax

//Once only initialisation
let raven = RavenBuilder("myStore")
raven {
       let! stored = storeMany (createCustomers 365)
       return stored
}

To query via combinators

let actual : seq<Customer> =
          query (where <@ fun x -> x.Dob < new DateTime(2012,2,1) @>)
          |> withSession "myStore"

or monadic

raven {
        let! actual = queryAllBy (where <@ fun x -> x.Dob < new DateTime(2012,8,1) @>)
        return actual
}

other more advanced scenarios are supported, for example server side joins,

raven {
      do! store customer >> ignore
      do! store order >> ignore
      return! (fun s ->
                     let order = ``include`` <@ fun s -> s.Customer @> (fun s -> s.Load("orders/1")) s
                     let customer : Customer = s.Load(order.Customer)
                     order, customer)
}

the code for this is hosted at Bitbucket feel free to check it out and contribute your own additions.

Posted in Development | Tagged , | Leave a comment