C Sharp

Using Dynamic Type Discovery to Select COM Interfaces

So, how does the classic QueryInterface scenario work from the perspective of the .NET client when it wants to access another interface implemented by the COM object? To QI for another interface, all you need to do is cast the current object to the other interface that you need and, voila, your QI is done! You are now ready to invoke all the methods and properties of the desired interface. It's that simple.

Again, the RCW does the all the hard work under the covers. In a way, it's analogous to the way that the Visual Basic runtime shields COM client programmers from having to write any explicit QueryInterface-related code-it simply does the QI for you when you set one object type to an object of another associated type.

Let's see this in action to find out how easy it is. In our example, suppose you wanted to call the methods on the IAirportFacilities interface, which is another interface implemented by our COM object. To do this, you'd cast the AirlineInfo object to the IAirportFacilities interface. You can now call all the methods that are a part of the IAirportFacilities interface. But before performing the cast, you might want to check whether the object instance that you're currently holding supports or implements the interface type that you're querying for. You can do this by using the IsInstanceOf method in the System.Type class. If it returns true, you know that the QI has succeeded and you can safely perform the cast. In case you cast the object to some arbitrary interface that the object does not support, a System.InvalidCastException exception is thrown. This way the RCW ensures that you're casting only to interfaces that are implemented by the COM object. Here's how all that looks in code: -

using System;
using System.Runtime.InteropServices;
using System.Reflection;
using AIRLINEINFORMATIONLib;
public class AirlineClient2App
{
    public static void Main()
    {
        ///////////////////////////////////////////////
        /// QUERY INTERFACE/ RT type Checking
        ///////////////////////////////////////////////
        try
        {
           AirlineInfo objAirlineInfo;
           IAirportFacilitiesInfo objFacilitiesInfo;
            // Create a new AirlineInfo object.
            objAirlineInfo = new AirlineInfo();
            // Invoke the GetAirlineTiming method.
            String strDetails = objAirlineInfo.GetAirlineTiming
                                        (strAirline);
            // QI for the IAirportFacilitiesInfo interface.
            objFacilitiesInfo =
                   (IAirportFacilitiesInfo)objAirlineInfo;
            //Invoke a method on the IAirportFacilitiesInfo
            //interface.
            Console.WriteLine("{0}",
            objFacilitiesInfo.GetInternetCafeLocations());
        }
        catch(InvalidCastException eCast)
        {
            Console.WriteLine("We got an InvalidCast Exception " +
                              "- Message is {0}",eCast.Message);
        }
    }
}