16 Apr
2010

Linfu Duck Typing Part 1 – Revealing Secrets

Category:UncategorizedTag: :

Don?t you just hate it when a class in the .NET Framework or another third-party library or framework provides that particular feature you?re looking for only to realize that this class has not been made accessible? One blatant example of this is the SqlCommandSet class in the System.Data.SqlClient namespace.

One can use reflection in order to access and use this private class. An even better and more efficient approach would be to use delegates instead. But there?s also another simple and elegant solution which I briefly mentioned in a previous post namely duck typing.

Now in order to access the SqlCommandSet class we need to define an interface with all of the methods we want to access from our code. Reflector can come in handy in this case to determine which particular methods we need.

public interface ISqlCommandSet : IDisposable
{
    SqlConnection Connection { get; set; }

    void Append(SqlCommand command);
    Int32 ExecuteNonQuery();
}

 

This is pretty much what we need from a SqlCommandSet. Now we can create a factory class for creating instances of the SqlCommandSet class.

public class SqlCommandSetFactory
{
    private readonly Type _typeOfSqlCommandSet;

    public SqlCommandSetFactory()
    {
        var system_data = Assembly.Load("System.Data, 
                                         Version=2.0.0.0, 
                                         Culture=neutral, 
                                         PublicKeyToken=b77a5c561934e089");
                                         
        _typeOfSqlCommandSet = 
            system_data.GetType("System.Data.SqlClient.SqlCommandSet");
    }

    public ISqlCommandSet CreateSqlCommandSet()
    {
        var instance = Activator.CreateInstance(_typeOfSqlCommandSet, true);
        var dynamicObject = new DynamicObject(instance);            
        return dynamicObject.CreateDuck<ISqlCommandSet>();
    }        
}

 

The System.Data assembly is loaded and the type of the SqlCommandSet is determined in the constructor of the factory class. In the factory method itself we first create an instance of the SqlCommandSet class and then use LinFu?s DynamicObject to ?cast? it to our ISqlCommandSet interface. And this is pretty much it. Now we can use a SqlCommandSet at will.

using(var connection = new SqlConnection(@"..."))
{
    connection.Open();

    using(var command1 = new SqlCommand("INSERT INTO BLABLA ..."))
    using(var command2 = new SqlCommand("INSERT INTO BLA BLA ..."))
    {
        var commandSet = new SqlCommandSetFactory().CreateSqlCommandSet();
        commandSet.Connection = connection;
        commandSet.Append(command1);
        commandSet.Append(command2);
        commandSet.ExecuteNonQuery();
    }
}

 

Again I?d like to mention that I?ve been using the DynamicObject class from Linfu 1.0 which you can download here.

Find me

RSS
Facebook
Twitter
LinkedIn
SOCIALICON
SOCIALICON

Disclaimer

The opinions and content expressed here are my own and not those of my employer.