COM Interoperability in .NET Framework: Part I
Part I: Using COM components in .NET framework
In this article we review the concepts & walk-through an example that demonstrates COM interoperability in .NET framework.
What is the need for Interoperability?
COM components have different internal architecture from .NETcomponents hence they are not innately compatible. Most organizations,which have built their enterprise applications on COM objects for theirmiddle tier services, cannot write off the investments on thesesolutions. These legacy components ought to be exploited by managedcode in .NET framework. This is where Interoperability pitches in; it'sa Runtime Callable Wrapper (RCW) that translates specific calls frommanaged clients into COM specific invocation requests on unmanaged COMcomponent. The method call on RCW will make .NET components believethat they are talking to just another .NET component.
Before we move on to the core concepts, lets have small primer on COM.
What is COM?
COM stands forComponent Object Model, which is binary specification for software codere-use. It imposes a standard for the interfaces through which clientcode talks to component classes. The component's IUnknown interfacehelps to maintain a reference count of the number of clients using thecomponent. When this count drops down to zero, the component isunloaded. All components should implement the IUnknown interface. Thereference count is maintained through IUnknow::AddRef() &IUnknow::Release() methods, interface discovery is handled throughIUnknow::QueryInterface().
What is Runtime Callable Wrapper?
.NET applicationcommunicates with a COM component through a managed wrapper of thecomponent called Runtime Callable Wrapper. It acts as managed proxy tothe unmanaged COM component.

When we make a method call, it goes onto RCWand not the object itself. RCW manages the lifetime management of theCOM component.
How is the Component Binding in interoperability?
Bindingrefers to information on methods, properties, events etc that clientneeds to know about the object. We still can use the good old techniqueof bindings in .NET interoperability viz., Early & Late bindings.Early Binding: Clients obtain compile time type information from thecomponent's type library
Late Binding: Clients lack rich type information of the object, it is known at runtime.
How do we implement COM Interoperability?
We can implement it in following steps: – Create Runtime Callable Wrapper out of COM component.
– Reference the metadata assembly Dll in the project and use its methods & properties.
Step 1:
There are two ways to generate managed metadata wrapper:
– Using Type Library Importer utility
– VS.NET IDE
Type Library Importer (tlbimp.exe) is commandline syntax, which converts COM specific type definition in a COM typelibrary into equivalent definitions for .NET wrapper assembly. Bydefault utility gives wrapper assembly same name as COM dll.

The above example generates metadata assemblywith the name "InteropExampleRCW.dll" out of COM component"InteropExample.dll" using the following syntax at VS.NET commandprompt.
tlbimp InteropExample.dll /output:InteropExampleRCW.dll /verbose
Note: it internally resolves ADODB references in the COM. Through "out" argument we can specify desired assembly name.
Type library importer interrogates COM dll'stype library and translates the information therein into .NET format.The metadata assembly so generated contains wrapper classes that can beused any .NET client e.g. C# windows clients. RCW is created on the flywhenever component is created & it acts like managed types to COMspecific data types.
VS.NET IDE also helps us generate metadata assembly:
Click on Project � Add reference� COM tab

The tab lists registered components on localmachine, select the desired COM dll and add to list of selectedcomponents. VS.NET automatically generates metadata assembly puttingthe classes provided by that component into a namespace with the samename as COM dll.
How is the structure of Wrapper Assembly?
For each class imported into wrapper assembly,two wrapper classes are generated. COM specific information can beviewed using MSIL Disassembler utility (ildasm .exe) at VS.NET commandprompt:
ildasm InteropExampleRCW.dll

InteropExample.dll (developed in VB6.0) component has the following public classes:
Authors
Titles
The generated assembly has four classes:
Authors, AuthorsClass
Titles, TitlesClass
First is the interface having the same GUID asthe original COM class, second is concrete class and whose instance isto be created. Concrete class is suffixed with the word "Class".Concrete class implements all the interfaces that are supported by theoriginal COM class.
All the generated types are place under the single namespace InteropExampleRCW
Step 2: Reference the metadata assembly Dll in the project and use its methods & properties:

Create a new C# Windows application project.Drag following label, textbox, datagrid controls on the form, and namethem accordingly, the form will appear as follows:

Import the required assemblies:
using System.Data;
using System.Data.OleDb;
Include following code in appropriate click events:
To use Authors search from AuthorClass, have code for Search Author button click event as:
private void btnSearchAuthors_Click(object sender, System.EventArgs e)
{
//create an instance of AuthorsClass from wrapper assembly
InteropExampleRCW.AuthorsClass myAuthorRCW=new InteropExampleRCW.AuthorsClass();
DataSet dsAuthorList=new DataSet("Authors");
OleDbDataAdapter daAuthRecs=new OleDbDataAdapter();
ADODB.Recordset rsAuthors=new ADODB.Recordset();
rsAuthors=myAuthorRCW.GetAuthors(txtAuthors.Text.ToString());
//invoke method from the RCW
daAuthRecs.Fill(dsAuthorList,rsAuthors,"Authors");
dataGridAuthors.SetDataBinding(dsAuthorList,"Authors");
}
To use Titles search from TitleClass, code for Search T
itle button click event:
private void btnSearchTitle_Click(object sender, System.EventArgs e)
{
InteropExampleRCW.TitlesClass myTitlesRCW=new InteropExampleRCW.TitlesClass();
DataSet dsTitleList=new DataSet("Titles");
OleDbDataAdapter daTitleRecs=new OleDbDataAdapter();
ADODB.Recordset rsTitles=new ADODB.Recordset();
rsTitles=myTitlesRCW.GetTitles(txtTitle.Text.ToString());
daTitleRecs.Fill(dsTitleList,rsTitles,"Titles");
dataGridTitle.SetDataBinding(dsTitleList,"Titles");
}
The output of the run will look like:

How Do I Release COM objects?
RuntimeCallable Wrapper is managed creation itself; hence its lifetime iscontrolled by Common Language Runtime. The COM component is freed frommemory when the garbage collector calls the Finalize() method on RCW.Internally RCW calls Release() of IUknown interface on COM object.
To explicitly remove COM objects from memoryinvoke the static method on Marshal class inSystem.Runtime.InteropServices namespace:
using System.Runtime.InteropServices;
Marshal.ReleaseComObject(myAuthorRCW);
About Author: Prashant Tailor isBachelor of Electronics Engineer, currently working as Microsoftsolution developer. He possesses 5 years of IT experience in analysis,design & development of client/server and web-applications usingVisual Basic, C#, ASP, COM/DCOM, SQL Server and Oracle.




10. Jan, 2007 by 







No comments yet... Be the first to leave a reply!