When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, January 8, 2003

COM Interoperability in the .NET Framework

By Prashant Tailor


Introduction


COM stands for Component Object Model, which is binary specification for software code re-use. It imposes a standard for the interfaces through which client code talks to component classes. Since classic ASP was limited in its functionality, in order to perform certain tasks in an ASP Web application, a COM component was needed. For example, creating images, examining the Event Log, or performing a remote HTTP request were all tasks that required a COM component.

- continued -

Additionally, COM components were commonly used to encapsulate business logic, as discussed in Using Business Objects in your ASP Web Application. An eCommerce Web site might create a COM component that had methods like CalculateShippingCosts(shoppingCartID) and CalculateArrivalDate(shipToZipCode), which would compute the shipping costs for the items in a particular user's shopping cart and calculate how long it would take a shipment to reach the buyer. The advantage to placing such business rules and logic in COM components includes improved code readability and maintainability.

Since ASP.NET Web pages have access to the classes in the .NET Framework, ASP.NET Web pages can, without components, perform tasks like creating images, examining the Event Log, or performing a remote HTTP requests. However, it is still a wise idea to encapsulate business logic into components, as discussed in the article Displaying Custom Classes in a DataGrid.

The components used by an ASP.NET Web page are commonly referred to as .NET components, and differ from COM components in a number of important ways. These differences mean that your ASP.NET Web pages cannot natively use COM components. Rather, some sidestepping must be done to allow for interoperability between classic COM components and an ASP.NET Web page. In this article we are going to look at the concepts and walk-through an example that demonstrates COM interoperability in the .NET Framework.

Providing Interoperability


COM components have different internal architecture from .NET components, hence they are not innately compatible. Most organizations, which have built their enterprise applications on COM objects for their middle tier services, cannot write off the investments on these solutions. That is, for such companies to migrate to ASP.NET there needs to be a way for the new ASP.NET Web pages to use the old, legacy COM components.

In order to have a COM component used through an ASP.NET Web page, we will be using what is called a Runtime Callable Wrapper (RCW). The RCW translates specific calls from the ASP.NET Web page into COM-specific invocation requests on a COM component. When using RCWs, our ASP.NET Web page will believe that it's talking to just another .NET component instead of talking to a COM component.

The following graphic depicts the RCWs role. On the left is the .NET Application (you can think of this as our ASP.NET Web page). On the right is the legacy COM component that we want our ASP.NET Web page to work with. In the middle sits the RCW, which accepts incoming requests from the ASP.NET Web page, translates them so that they can be handled by the COM component, and then passes them onto the COM component. Essentially, the RCW acts as managed proxy to the unmanaged COM component.

When we make a method call, it goes onto RCW and not the object itself. RCW manages the lifetime management of the COM component.

Creating the Runtime Callable Wrapper


There are two ways to create the runtime callable wrapper:
  • Through the Visual Studio .NET IDE
  • Using Type Library Importer utility (executed via the commandline using tblimp.exe) - you must use this approach if you do not have Visual Studio .NET installed
The Type Library Importer is command line program that converts COM specific type definition in a COM type library into equivalent definitions for .NET wrapper assembly. For example, to generate a metadata assembly with the name InteropExampleRCW.dll from a legacy COM component named InteropExample.dll, the following syntax can be used from the Windows command prompt:

tlbimp  InteropExample.dll  /output:InteropExampleRCW.dll /verbose

(If you'd like, you can view a screenshot of tlbimp.exe in use.)

The Type Library Importer interrogates the COM DLL's type library and translates the information therein into .NET format. The metadata assembly generated contains wrapper classes that can be used any .NET client - an ASP.NET Web page, a C# windows clients, and so on. The RCW is created on the fly whenever component is created and acts like managed types to COM specific data types.

In addition to being able to create a RCW through the commandline, we can also create an RCW via Visual Studio .NET. In order to accomplish this, click on Project / Add Reference / COM Tab, which will show a dialog box similar to the one below. The tab lists registered components on the local machine. Simply select the desired COM DLL and add it to list of selected components. Once you click OK, VS.NET will automatically generate metadata assembly and place the classes provided by that component into a namespace with the same name as COM DLL.

Examining the Structure of Wrapper Assembly


In order to understand how to use the RCW it is important that we know the structure of the wrapper assembly (the wrapper assembly is the DLL file created by tlbimp.exe or the VS.NET IDE). To examine the wrapper assembly, you can use Microsoft's .NET disassembler, ildasm.exe, in the following manner from the command prompt:

ildasm AssemblyName.dll

In the download section at the end of this article I have created a simple example VB 6.0 COM component that has two classes: Authors and Titles. When creating the RCW, a new assembly will be generated, which has the following two classes:

  • AuthorsClass
  • TitlesClass
(along with a number of interfaces). Note that the class name for the RCW is simply the name of the public class in the COM component, followed by the string "Class". The AuthorsClass class contains the same methods and properties that the COM component's Authors class contains. That is, the AuthorsClass has the method GetAuthors() and the TitlesClass has the method GetTitles(), which are the methods found in the original COM component. (You can view a screenshot of ILDASM in action.)

Using the Legacy COM Component in an ASP.NET Web Page via the RCW


If you are using Visual Studio .NET, the first step is to add the new .NET component (the RCW) to your project. You can do this by going to Project / Add Reference / .NET tab, and choosing the RCW you created for the legacy COM component that you want to use. If you are not using VS.NET, then you will manually need to copy the RCW assembly (the DLL file) into your Web application's /bin directory.

From here, you can just use the appropriate RCW class as an interface into the legacy COM component. For example, the following source code comes from the source code included at the end of this article, and creates an instance of the RCW's AuthorsClass and calls its GetAuthors() method. This method accepts a string parameter and returns an ADODB Recordset containing authors that match the string query:

// create a new instance of the Authors class
InteropExampleRCW.AuthorsClass myAuthorRCW=new InteropExampleRCW.AuthorsClass();
 
// Build a new DataSet
DataSet dsAuthorList=new DataSet("Authors");

// Create an OleDBDataAdapater to fill the DataSet
OleDbDataAdapter daAuthRecs=new OleDbDataAdapter();

// Use the ADODB.Recordset object to hold the results of the
// GetAuthors() method call
ADODB.Recordset rsAuthors=new ADODB.Recordset(); 
rsAuthors=myAuthorRCW.GetAuthors(txtAuthors.Text.ToString()); 

// populate the DataSet with the ADODB.Recordset returned
daAuthRecs.Fill(dsAuthorList,rsAuthors,"Authors"); 

// bind the results to a DataGrid
dataGridAuthors.SetDataBinding(dsAuthorList,"Authors");  

The above code uses the ADODB.Recordset object, since the legacy COM component's GetAuthors() method returns an ADODB Recordset object. In order to use this code you will need to include a reference to the Microsoft ActiveX Data Objects 2.7 Library, which can be accomplished by going to Project / Add Reference / COM tab, and selecting the appropriate COM object. A future article of mine will talk about using the ADODB services in an ASP.NET Web page in much greater detail...

The above code starts by creating an instance of the RCW's AuthorsClass class. Recall that this class serves as a proxy between your ASP.NET Web page and the COM component. That is, when the RCW's GetAuthors() method is called, the call ispasssed onto the COM component, which then runs and returns a value, which is passed through the RCW back up to your ASP.NET Web page. So, by using the RCW you are using the legacy COM component, calling its methods. The RCW serves as an intermediary of sorts.

Once an instance of the AuthorsClass class has been created, an ADODB.Recordset object is created and assigned the return value of the GetAuthors() method call. This ADODB.Recordset is then used to fill a DataSet, which is then bound to a DataGrid. To summarize, the above code gets an ADODB Recordset back from a legacy COM component, and displays the resulting Recordset in a DataGrid.

Conclusion


In this article we examined how to use runtime callable wrappers (RCW) to allow for an ASP.NET Web page to call a COM component. Creating the RCW is fairly simple, and can be done either via the commandline or through the Visual Studio .NET IDE. Once the RCW has been created, it needs to only be included in the Web application and then you can start using it in your ASP.NET Web pages. Through this means you can use legacy COM components in your .NET applications!

Happy Programming!

  • By Prashant Tailor


    Attachments


  • Download sample code (in ZIP format)


    About the Author


    Prashant Tailor is Bachelor of Electronics Engineer, currently working as Microsoft solution developer. He possesses 5 years of IT experience in analysis, design and development of client/server and Web-applications using Visual Basic, C#, ASP, COM/DCOM, SQL Server and Oracle.



  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article