Choose Your Own Adventure Type Provider

by Pezi 29. July 2013 01:21

That's right.. the type provider everyone has been waiting for, the choose your own adventure type provider!

This is completely pointless and silly, something I just wrote this afternoon.  I had various discussions with Phil Trelford about this and finally decided to do it.

Unfortunately none of the real CYOA books are out of copyright and there appears to be very little in the way of other free ones that I can  find.  I did however find this one rather silly story on smashwords which is free, it's not quite normal CYOA fare and you can't lose, but it serves to illustrate the provider.

The provider reads a data file which contains the contents of each page on a line,  the index of the page and any choices the page has on it along with the index that each choice points to.  This then creates a type system with properties that you can navigate via intellisense.  

#r @"F:\dropbox\CYOAProvider\CYOAProvider\bin\Debug\CYOAProvider.dll "
type adventure = CYOAProvider.CYOAProvider< @"F:\dropbox\CYOAProvider\data.dat">

let a = adventure()

a.Intro  // start your adventure here!

You can find this ridiculous type provider on GitHub here

To create the data file I wrote an amazing C# GUI, if you want to create a file yourself and would like the program to work with then mail me :) 


F# | type providers

Microsoft Dynamics CRM Type Provider preview

by Pezi 30. December 2012 03:50

Are you tired of generating strongly typed classes with millions of lines of C# using crmsvcutil.exe that often crashes?  Fed up with having to re-generate the classes every time something in the schema changes?  Feeling restricted by the LINQ provider's limitations?  Ever wonder why you should need to know what attribute joins to what in your relationships to perform your joins? F# to the rescue!

I am working on a F# type provider than aims to solve a lot of these pains, and more besides!  This is just a sneak preview with what is to come, I have not released any of this yet.  First, here is an example of a rather silly but fairly complex query using the new type provider and the F# query syntax :

type XRM = Common.XRM.TypeProvider.XrmDataProvider<"http://something/Organization.svc">

let dc = XRM.GetDataContext()

type TestRecord = 
    { x : string; 
      y : int }

let test = { x = "John%"; y = 42 }

let q =
    query { for s in dc.new_squirrel do                            
            where (s.new_name <>% test.x || s.new_age = test.y)
            for f in s.``N:1 <- new_new_forest_new_squirrel`` do
            for o in f.``N:1 <- owner_new_forest`` do
            where (s.new_colour |=| [|"Pink";"Red"|])
            where (f.new_name = "Sherwood")
            where ( = "PEZI THE OWNER!")
            select (s, f.new_name, f, o) }

This example illustrates several cool features of the F# type provider ;

  • No code generation here - these "virtual" types are magically created on the fly by the compiler, using the organization service's metadata capabilities.  This provides full intellisense and only lazily loads the entity attributes and relationships on demand.  If your schema changes and breaks something, the code will not compile.
  • Where clauses can appear anywhere and be as complex as you want.  the only restriction is that only one entity type is used in each clause - this is because mixing OR logic between entities is impossible to translate into the underlying QueryExpression tree.
  • Relationships can be accessed via the SelectMany (for) syntax.  In this example Squirrel is the ultimate child and the code is traversing up the relationships through its parents (forest, and then owner).  Instead of needing to know or care about how these relationships are joined, this is handled for you in the magic.  Additionally, should you care, the intellisense will show you exactly what attribute is being joined to what.  It is also possible to start at a parent and traverse down the one-to-many relationships, as long as you don't branch off anywhere to more than one child as this is not supported in the underlying provider.
  • Custom operators!  F# lets you define your own operators. Currently I am supporting =% (like) <>% (not like)  |=| (in) and |<>| (not in) however it will be very easy to add more of these, or extensions to the relevant types to implement the wealth of other, sometimes rather exotic, XRM condition operators, of which almost all are not currently accessible from the existing LINQ provider, including in and not in. 
  • Projection expression - not only can you access attributes and perform any transformation, you may have noticed it allows you to select entire parent entities - you cannot do this in the current LINQ provider because the QueryExpression is only capable of returning an single entity type which has to be the ultimate child that you are selecting.  Any attributes from parents are kind of shoehorned into the result entity with aliases - more magic in the type provider enables you to select all the entities out as real CRM entities :) 
Joins are also still supported should you wish to use them explicitly for some reason.  At runtime, these "virtual" entities get "erased down" to a XrmEntity which is a thin wrapper inheriting from Entity - this means the resulting objects you can use everywhere like you normally would in your CRM code. 
Lots of stuff to come - paging, many LINQ execution methods, ordering, possibly even an auto conversion to fetchxml which will enable aggregate operations...


F# | type providers