COM Interop without referencing COM assemblies using Dynamic C#


Dynamics is a very strong yet quite under utilised feature of C# which came with C# version 4.0. The primary premise for its usage is that the “object type or data structure is not known at compile time”. In these cases the using the dynamic keyword basically tells the C# compiler to defer it evaluating the object type/ data structure to run time instead of compile time. This functionality or capability comes from another language runtime that sits on top of the CLR (Common Language Runtime) called the DLR (Dynamic Language Runtime).

Dynamics has a lot of use cases in the .Net Framework, one of which is interacting with COM components without having to actually add references to the Primary COM Interop assemblies. Below I just wanted to show a little use case where we can use dynamic to create an Excel document without referencing the following Excel Interop assembly:

  • Microsoft.Office.Interop.Excel

Now ofcourse, you would have to have Excel installed on the system where the code would run, but we will eliminate the need to reference the COM interop assemblies to our project. Also with use of dynamics one would need to have knowledge of the library since we do not get any intellisense support in Visual Studio once an object is declared as dynamic. This is solely because of the fact that the compiler does not know the type of the object until its evaluated at run time. So you would only see the base object methods on the intellisense.

My intent here is not to create a fully featured application, rather to just show the use case of how we can use dynamics to interact with COM Interop assemblies without actually having to reference them in our projects.

I am going to create a simple Console application that will launch an Excel, open a worksheet and add some information to the rows and columns. The sample code for the simple application is available on github.

I am going to create a simple Person class, the data for which we will add to Excel.

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

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Create a Console application and add a reference to the following assembly

AddReferenceInteropExcel

This example opens Excel WITH the primary interop assembly reference

class Program
{
    static List<Person> persons = new List<Person>();
    static Program()
    {
        persons.Add(new Person("Frank", 25));
        persons.Add(new Person("Joe", 24));
    }
 
    static void Main(string[] args)
    {
        var excelType = new Microsoft.Office.Interop.Excel.Application();
        excelType.Visible = true;
 
        excelType.Workbooks.Add();
        Worksheet workSheet = excelType.ActiveSheet;
 
        workSheet.Cells[1, 1] = "Names";
        workSheet.Cells[1, 2] = "Age";
 
        int rowIndex = 1;
        foreach (var person in persons)
        {
            rowIndex++;
            workSheet.Cells[rowIndex, 1] = person.Name;
            workSheet.Cells[rowIndex, 2] = person.Age;
        }
    }
}

And the same example WITHOUT using the Excel interop assembly:


class Program
{
    static List<Person> persons = new List<Person>();
    static Program()
    {
        persons.Add(new Person("Frank", 25));
        persons.Add(new Person("Joe", 24));
    }

    static void Main(string[] args)
    {
        dynamic excelType = Type.GetTypeFromProgID("Excel.Application");
        excelType.Visible = true;

        excelType.Workbooks.Add();
        dynamic workSheet = excelType.ActiveSheet;

        workSheet.Cells[1, 1] = "Names";
        workSheet.Cells[1, 2] = "Age";

        int rowIndex = 1;
        foreach (var person in persons)
        {
            rowIndex++;
            workSheet.Cells[rowIndex, 1] = person.Name;
            workSheet.Cells[rowIndex, 2] = person.Age;
        }
    }
}

We get the type of the Excel application using the Type.GetTypeFromProgID into a dynamic variable. Now we can program assuming that at Runtime the variable excelType will be evaluated to Excel.Application. As long as that happens during the run time our program will run just fine. However, its noteworthy that in case the type doesn’t evaluate to Excel.Application at runtime a RunTimeBinderException will be thrown when we try to access any properties or methods on the excelType variable.

So as we can see, Dynamic C# provides a very powerful mechanism that compliments the statically defined C# bindings and can also be used to interact with other dynamic langauages like Iron Python etc without much code clutter.