Friday, August 3, 2012

Two more Type Provider samples

After I have the wrapper sample which insert the logging code, I start to think if there is another way to explore the meta-programming more with type provider. Computer code is also data with schema information and this is something I am more familiar and interested. Another takeaway is the type provider can get information from at least four sources to generate code.
  1. static parameter, such as RegularExpressionTypeProvider<"regular expression pattern">
  2. external source, such as local file or database. One sample is the MiniCSVTypeProvider<"local csv file">
  3. the module which provides variable can also be the source to provide information to generate code. (See first sample)
The sample is a "multi-inheritance" type provider to show how type provider can rearrange the class member and give a better (or different) experience. I am not going to claim the experience is enjoyable for everyone, but at least you have the chance to cook the stuff you like. 

The first and easy to understand sample is here. It create instance of two sealed C# class instance and use type provider to generate provided methods. It seems that the new type is inherit from two sealed class, but actually it is just calling to a wrapper. The C# class is defined as the following. I made them sealed, but this technique works for any class. If the two base class have the function with same name and signature, you will have the liberty to decide how to handle this situation rather than obey the dictation from the compiler.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public sealed class Class1
    {
        public void F1()
        {
            Console.WriteLine("from Class1.F1");
        }

        public void F2()
        {
            Console.WriteLine("from Class1.F2");
        }
    }

    public sealed class Class2
    {
        public void F11()
        {
            Console.WriteLine("from Class2.F11");
        }

        public void F12()
        {
            Console.WriteLine("from Class2.F12");
        }
    }
}

The "multi-inheritance" is achieved by using a wrapper class like:

public class WrapperClass
{
    public Class1 c1;
    public Class2 c2;
    public void F1() { c1.F1(); }
    public void F2() { c1.F2(); }
    public void F11() { c2.F11(); }
   public void F12() { c2.F12(); }
}

The main pain point for this project is write the code quotation, I will have a separate thread to discuss how to write quotation.

The sample code here is to show how to use the Activator.CreateInstance to create two sealed C# class instance and generate a "multi-inheritance" class. This version is the first time I tried to pass the type name into the type provider, the experience, to be honest, is horrible. :-(. I listed here only because it might serve as a general template for some cases and people can use it to find the code quotation they need.

Type provider is really a huge topic when I dig deeper and deeper, hopefully you enjoy it as I do. :)

2 comments:

Mauricio Scheffer said...

Cool! But please consider posting these samples on a code hosting site like github, codeplex, bitbucket, so we can review things without having to download everything.

Tao Liu said...

Yes, I will do that. Eventually all these samples will go to the F# 3.0 sample pack.