Introduction

Here I describe a unique way of casting any object to an interface that it actually exposes, even though it does not formally implement the particular interface. In order to get the idea what I’m trying to propose here, consider examples below.

Lets say you’re utilizing 3rd party libraries(LibA and LibB) that are dealing with persons. These libraries have PersonLibA and PersonLibB classes defined and are exposing instances of these persons. Most likely they would expose similar public interface and would have properties like Name, EMail, Address, DateOfBirth, etc.  I’m almost sure that you would like to access these persons uniformly. If you had the source code of these components, you could define a common interface and implement PersonLibA and PersonLibB classes from your newly defined interface. However, if the source code is not available that would not work out. The only thing left to do is to define wrapper classes for each of person classes and implement the common interface.

Similarly, if you want to access the Text property of WPF TextBox and TextBlock uniformly, you would most probably need to define two wrapper classes to expose the Text property.

It can be done easily if there are not so many 3rd party classes involved and the common interface is simple enough. Otherwise, this process would be really painful. What I suggest here is a utility class that casts an object to an interface by generating wrapper class on fly and doing all the dirty work for you behind the scenes. I will go straight to the usage and later on will present some tricks used in the solution.

Using the code

The utility comes as a template class where T is the the interface to convert to. It has the only single public method - T As(object o) which gets any kind of object and returns converted wrapper object if succeeded.

public static class ObjectCaster<T>
{
    public static T As(object o)
    {
        // ....
    }
}

Consider the following Person class. Note that it does not implement any interface.

public class Person
{
    public string Name { get; set; }

    public event EventHandler Initialized;

    public void Initialize()
    {
        Name = "Initialized";
        EventHandler e = Initialized;
        if (e != null)
            e(this, EventArgs.Empty);
    }
}

However, it is perfectly aligned with the following interface:

public interface IPerson
{
    string Name { get; set; }

    event EventHandler Initialized;

    void Initialize();
}

Below is the actual demo code which utilizes ObjectCaster class and converts an instance of Person class to IPerson interface (line 4).

Person obj = new Person() { Name = "John" };
Console.WriteLine(string.Format("(obj is IPerson) == {0}", obj is IPerson));

IPerson iperson = ObjectCaster<IPerson>.As(obj);
iperson.Initialized += ((sender, e) => Console.WriteLine("Initialized Called"));

Console.WriteLine("Person> " + obj.Name);
Console.WriteLine("IPerson> " + iperson.Name);

iperson.Name = &quot;Steve&quot;;

Console.WriteLine("Person> " + obj.Name);
Console.WriteLine("IPerson> " + iperson.Name);

iperson.Initialize();

Console.WriteLine("Person> " + obj.Name);
Console.WriteLine("IPerson> " + iperson.Name);

As you see the output of code above, you will easily notice that the object does not formally implement IPerson interface, and correctly wraps properties, methods and events. You may also notice, that wrapped event handler modifies the value of original sender (which is instance of Person) to instance of converted wrapper object (iperson variable).

Background

The key point of the solution is concentrated in the GenerateProxyClass method:

private static CodeCompileUnit GenerateProxyClass(Type interfaceType, Type sourceType)
{
    //...
}

Basically, it generates a new proxy class using System.CodeDom machinery, which wraps the sourceType and implements the interfaceType interface. With the help of .NET Reflections it goes over members of interfaceType type and generates corresponding members in the proxy class. After it compiles the generated class utilizing CodeDomProvider class and calling CompileAssemblyFromDom method. At this point the generated class is compiled and the last thing to do is to create a new instance of the proxy class, and provide the source object as a constructor. Full source code for the utility class and demo application are available below in the downloads section.

Future Work

Next thing to do on this topic is to provide an ability to remap member naming and add type conversion. It will allow to cast to same an interface even though name and type of members are not the same in the interface and source classes.

Downloads