En la entrada anterior vimos qué era un TypeProvider y cómo funcionaba. Ahora vamos a ver cómo crear uno.
Lo primero que tenemos que tener en cuenta a la hora de crear un TypeProvider es tener un esquema de datos, y que además, este sea fijo y no cambie a lo largo de la ejecución de nuestro programa.
Teniendo esto claro, podemos proceder a crear una nueva solución y le añadimos un proyecto de librería. Hay un paquete en nuget que nos ayudará a crear nuestro TypeProvider, Fsharp.TypeProvider.StarterPack Lo añadimos al proyecto y por último añadimos un nuevo fichero de código *al final* de nuestro proyecto. Como veis los que lo habréis intentado tiempo atrás, ahora es mucho más sencillo configurar el entorno para crear nuestros propios TypeProviders.
Implementando un TypeProvider simple
En el fichero que añadimos, escribimos el siguiente código:

namespace TypeProvidersGeeksMs
 
open System 
open System.Reflection 
open ProviderImplementation.ProvidedTypes 
open Microsoft.FSharp.Core.CompilerServices 
open Microsoft.FSharp.Quotations 
 
 
 
[<TypeProvider>]
type SampleTypeProvider(config: TypeProviderConfig) as x = 
    inherit TypeProviderForNamespaces()
 
    let ns = "Geeks.SampleTypeProvider"
    let asm = Assembly.GetExecutingAssembly()
    
    let doASimpleType() = 
        let t = ProvidedTypeDefinition(asm,ns,"NombreDeLaClase",Some typeof<obj>)
        t.IsErased <- false
        //Propiedad estática
      let staticProp = ProvidedProperty("StaticProperty",typeof<string>,IsStatic=true,GetterCode= 
                                          (fun args -> 
                                          <@@ "Hello Geeks!" @@>))
       t.AddMember staticProp
       //Un constructor
       let ctor = ProvidedConstructor(parameters = [ ], 
                                       InvokeCode= (fun args -> 
                                       <@@ "The object data" :> obj @@>))
 
       t.AddMember ctor
 
       let prop = ProvidedProperty("InstanceProperty",typeof<string>,IsStatic=false,GetterCode= 
                                          (fun args -> 
                                          <@@ "Hello Geeks! Desde una propiedad de instancia" @@>))
 
       t.AddMember prop
 
 
        t
 
 
    let types = [doASimpleType()]
 
    do x.AddNamespace(ns,types)
    
[<assembly:TypeProviderAssembly>]  
do()



Estamos definiendo una clase que sigue un protocolo especifico: hereda de TypeProviderForNamespaces, y está marcada con el atributo TypeProvider.
Si ignoramos por un momento la función doASimpleType(), veremos que definimos dos valores previos, el espacio de nombres y el ensamblado. También declaramos un valor types (que contendrá una lista con los tipos que generará) nuestro TypeProvider y por último, dentro del mismo tipo del TypeProvider en sí, lo añadimos al namespace. Finalmente, fuera del tipo principal, añadimos un atributo de ensamblado para indicar que estamos creando un TypeProvider.
La función que genera los tipos es doASimpleType, en el primer método empezamos a definir el tipo en sí, que como vemos es una función que recibe un ensamblado, namespace, un nombre para el tipo (la clase se llamará “NombreDeLaClase”) y un option (aka maybe monad) type del tipo base, en este caso Object. Posteriormente, lo marcamos como generativo, indicando que no es erased (ver entrada anterior). Y a partir de este momento, comenzamos a añadirle miembros. Añadimos una propiedad estática, un constructor y una propiedad de instancia, el procedimiento es muy similar en todos los casos: definimos el miembro y sus parámetros (en caso que sea necesario) el código que utilizará vía quotations o “expresiones de código delimitadas» (más adelante hablaremos de esto, http://msdn.microsoft.com/es-es/library/dd233212.aspx). Y finalmente, nuestro método devuelve el tipo que hemos creado. 
He intentado mantenerlo muy simple para no perdernos demasiado en los detalles, aunque como os imaginaréis esto es solo la punta del iceberg. Se quedan muchas cosas en el tintero,como que también es posible añadir miembros a posteriori (aquí un ejemplo http://www.solveet.com/exercises/Maquina-de-Turing-en-el-sistema-de-tipos/278/solution-1912)

Consumiendo el TypeProvider 
Añadimos un nuevo proyecto de Fsharp de consola y referenciamos la dll compilada (seguramente nos salte un diálogo alertandonos de problemas de seguridad). Lo siguiente que debemos hacer es referenciar el namespace (Geeks.SampleTypeProvider) y crear un alias del tipo (para indicar al compilador que emita el código del TP) 
type AliasForNombredeLaClase = NombreDeLaClase
[<EntryPoint>]
    let main argv = 
        let sample = AliasForNombreDeLaClase()
        printfn "%A" sample.InstanceProperty
        0 
Si todo ha ido bien el código anterior no debería de marcar ningún error. En teoría para consumir el TP desde CSharp bastaría con referenciar este último proyecto. 
Un detalle a tener en cuenta, es que cada vez que queramos cambiar el TP, vamos a tener que cerrar VisualStudio y eliminar la carpeta bin del proyecto que contiene el TP.