Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

C# Object to Interface Caster Utility

4.94/5 (21 votes)
28 Apr 2009CPOL3 min read 61.2K   533  
A utility that casts an object to an interface, even if it doesn't formally implement it.

Introduction

In this article, 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 an idea of what I’m trying to propose here, consider the examples below.

Let's say you’re utilizing third party libraries (LibA and LibB) that are dealing with persons. These libraries have the PersonLibA and PersonLibB classes defined, and are exposing instances of these persons. Most likely, they would expose a 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 have the source code of these components, you could define a common interface and implement the 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 the person classes and implement the common interface.

Similarly, if you want to access the Text property of a 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 third 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 a wrapper class on the 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 a single public method, T As(object o), which gets any kind of object, and returns the converted wrapper object if succeeded.

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

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

C#
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:

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

    event EventHandler Initialized;

    void Initialize();
}

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

C#
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 = "Steve";

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 the code above, you will easily notice that the object does not formally implement the IPerson interface, and correctly wraps the properties, methods, and events. You may also notice that the wrapped event handler modifies the value of the original sender (which is an instance of Person) to an instance of the converted wrapper object (iperson variable).

binary_CSharp_Object_Caster

Background

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

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

Basically, it generates a new proxy class using the System.CodeDom machinery, which wraps the sourceType and implements the interfaceType interface. With the help of .NET Reflection, it goes over the members of the interfaceType type and generates the corresponding members in the proxy class. After that, it compiles the generated class utilizing the CodeDomProvider class and calling the 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. The full source code for the utility class and the demo application are available above in the downloads section.

Future work

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

Origin

The origin of this article can be found at: C# Object to Interface Caster Utility.

History

  • 26 April, 2009 - Fixed a bug to support non GACed assemblies. Thanks to Oleg Shilo.
  • 25 April, 2009 - Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)