Calling COM Objects from .NET


Having taken a look at some of the features and functionalities available in the .NET platform, you can see that the .NET platform is a major change from the Microsoft COM/COM+/ASP-based DNA technologies. Whereas on one hand it becomes imperative for technology architects and developers to understand and utilize the capabilities present in this new and enriched platform, it is probably equally important to understand how .NET interoperates with existing technology. Over the years, COM has been the de-facto standard for application development on the Microsoft Windows platform. And in these years , developers have churned thousands and, in some organizations, even millions of lines of source code deployed as either COM objects or native DLLs.

Take the scenario, for instance, of a financial services organization. Financial services organizations have typically invested heavily in custom application development as their unique business model, and requirements often don't get addressed by the larger off-the-shelf packaged Enterprise Resource Planning (ERP) vendors . A number of these custom applications are also termed mission critical, based on their importance to the business.

Consider, for example, a trading application that has been developed using a Visual Basic “based front end and a Microsoft SQL Server (or Oracle) “based relational database; and the application also interfaces with several other legacy mainframe applications. If the application has been designed properly ” specifically , the business logic has been separated from the graphical user interface (GUI) design ”typically, a pool of COM components would essentially represent the complex trading algorithms. The application has been in production in the organization for quite some time and over this time, the technology and business managers have realized the potential of providing a subset of the application on the Internet for power traders to execute trades in a self-service fashion. Given the time frame of this development and the maturity of the .NET platform, the architects decide that they will build this new add-on application front end to the existing application using ASP.NET and other technologies of .NET Framework. In fact, they have even explored the idea of utilizing the ASP.NET “based mobile Web application so that the application can be used by people on the go from their wirelessly connected mobile phones or PDA devices. Additionally, they also want to leverage this effort to explore how some of their B2B trading partners can directly integrate with their application in real-time using Web services instead of using the traditional batch-based complex file-based integration. Figure 11.1 shows an example of using COM and .NET.

Figure 11.1. Using COM and .NET together.

Indeed, ASP.NET provides the required set of technologies to create a scalable Web-based front end for the trading application. There are two options for the application back end and business logic: Either rewrite (or migrate) the existing business logic (which could be thousands and thousands of lines of code) into the .NET platform, or figure out a way to leverage those COM components from .NET components. This is exactly where COM Interoperability, better known as COM Interop fits in.

COM Interop provides a set of tools and technologies that allows developers to utilize existing investments in COM technologies in next -generation .NET applications and Web services. Given the background of this chapter, you will explore these tools and understand how COM Interop works.

Using the .NET Framework SDK ”Interop Assembly

As part of the .NET Framework SDK, command-line based tools are provided, which automate the process of creating a special assembly called the Interop Assembly (see Figure 11.2). Whereas .NET assemblies typically contain metadata and MSIL-based code, wrappers are .NET assemblies that contain the metadata for enabling the underlying COM invocations, through Runtime-Callable Wrappers (RCWs).

Figure 11.2. Interop Assemblies.

Suppose that you have developed the following Visual Basic “based COM component, which executes a trade (MyTradeSystem. Trader ). To be brief, the actual business logic that does the trade isn't shown in the code snippet that follows :

 
 ' FileName: Trader.vb VERSION 1.0 CLASS BEGIN   MultiUse = -1  'True   Persistable = 0  'NotPersistable   DataBindingBehavior = 0  'vbNone   DataSourceBehavior  = 0  'vbNone   MTSTransactionMode  = 0  'NotAnMTSObject END Attribute VB_Name = "Trader" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = True Public Function ExecTrade(ByVal equity As String, _        ByVal buyer As String, ByVal price As String) As Integer     Debug.Print "Trade Executed"     'Actual Business Logic of the Function     ExecTrade = 1 End Function 

The preceding COM object is first compiled into a DLL (in this case Trade.dll) using Visual Basic 6.0. Next, using the Type Library to Assembly Converter utility, TLBIMP.EXE, found in the .NET Framework SDK, you can generate the Interop Assembly.

 
 tlbImp Trade.dll 

Now that the Interop Assembly has been generated (by default, in this case, it would be TraderApp.dll), you can utilize the generated Interop Assembly in your .NET components written in any .NET-supported language. Of course, if not already done, the original COM component needs to be registered in the Windows Registry (using regsvr32 Trade.dll).

 
 Imports System Imports TradingApp Module Trade       Sub Main()          Dim tr as New TraderClass          Console.WriteLine(tr.ExecTrade("MSFT","hitesh.seth","50"))       End Sub End Module 

To compile the code successfully, you would need to reference the Interop Trade Assembly using the Visual Basic .NET command-line compiler's option /lib.

 
 vbc Trade.vb /r:TradingApp.dll 

To further illustrate that the Interop Assembly is really like any other .NET assembly and can be utilized from .NET-supported programming languages, take a look at the code snippet in C#.

 
 using System; using TradingApp; class Trade {    static void Main() {       Trader tr = new Trader();       Console.WriteLine(tr.ExecTrade("MSFT","hitesh.seth","50"));    } } 

The C# code can be further compiled using the command-line C# compiler as well, also referencing the same TradingApp Interop Assembly.

 
 csc Trade.cs /r:TradingApp.dll 

Using Visual Studio .NET

If you are using the Visual Studio .NET application development environment, you are in luck. The process of converting a type library to an Interop Assembly can be automated by using Visual Studio .NET by simply adding a reference to a COM object (see Figure 11.3). You can initiate this through the Add Reference menu item in the References section of Solution Explorer (or through Project, Add Reference, COM).

Figure 11.3. Interoperability with COM components using Visual Studio .NET.

As soon as the link is added to the COM object, Visual Studio .NET automatically generates, behind the scenes, an Interop Assembly that is automatically linked with the project. In nutshell , it is almost the same process used, but as expected, Visual Studio .NET provides the added ease of use. For more advanced interoperability, the command-line utility provides a larger set of command-line options that fine tune the process of Interop Assembly generation. It is safe to say that if you have access to the Visual Studio .NET toolset, you can use it for most common interoperability tasks . Command-line utilities also are included with Visual Studio .NET because it includes the .NET Framework SDK.

Using Excel from .NET Components

For years, Microsoft's own technologies, including Microsoft Windows variants, Microsoft Office, and back-end server technologies, have utilized the COM programming model. Office applications, particularly Microsoft Excel, have also been used within other applications for charting and reporting because of the ease of use and ubiquity of these products. In fact, a number of third-party products have developed Excel-based reporting solutions. As an enhanced version of the COM interoperability, you will develop a simple application that uses Excel to report basic employee information (see Figure 11.4). First, take a look at the Visual Basic .NET client (Listing 11.1), utilizing the Interop Assemblies:

Listing 11.1 Using Excel Automation Objects from .NET Applications
 Option Explicit On  Imports Microsoft.Office.Interop Imports System.Data.SqlClient Module ExcelExport     Sub Main()         Dim xlApp As Excel.Application         Dim xlBook As Excel.Workbook         Dim xlSheet As Excel.Worksheet         xlApp = New Excel.Application         xlBook = xlApp.Workbooks.Add()         xlSheet = xlBook.ActiveSheet         xlSheet.Cells(1, 1) = "Employee Name"         xlSheet.Cells(1, 2) = "Email"         xlSheet.Cells(1, 3) = "Tel (Direct)"         xlSheet.Cells(1, 4) = "Tel (Cell)"         Dim ds As DataSet = GetEmployees()         Dim dt As DataTable = ds.Tables.Item("Employees")         Dim rowEmployee As DataRow         Dim rowNo As Integer         rowNo = 2         For Each rowEmployee In dt.Rows             xlSheet.Cells(rowNo, 1) = rowEmployee.Item("Name")             xlSheet.Cells(rowNo, 2) = rowEmployee.Item("Email")             xlSheet.Cells(rowNo, 3) = rowEmployee.Item("Direct")             xlSheet.Cells(rowNo, 4) = rowEmployee.Item("Cell")             rowNo += 1         Next         xlApp.Visible = True         xlApp.UserControl = True         xlBook = Nothing         xlSheet = Nothing         xlApp = Nothing     End Sub     Function GetEmployees() As DataSet         Dim strConn = "Data Source=POWER2003;Initial Catalog=Book;" _             & "User ID=sa;Password=sa"         Dim cn As New SqlConnection(strConn)         cn.Open()         Dim strSelectSql As String = "select * From Employees"         Dim cmdSelect As New SqlDataAdapter(strSelectSql, cn)         Dim ds As New DataSet         cmdSelect.Fill(ds, "Employees")         cn.Close()         GetEmployees = ds     End Function End Module 
Figure 11.4. Using Excel Automation objects from .NET applications.

Using ActiveX Controls in Web Forms

Similar to using COM objects within .NET components, ActiveX controls can be used inside Web forms. Key application areas include utilizing Microsoft Internet Explorer within a .NET application or using the large set of ActiveX controls that you may have procured to be used in COM-based applications.

Even though it is not required, I would highly recommend using the Visual Studio .NET environment for using ActiveX controls because it provides the familiar drag-and-drop environment where ActiveX controls can be used with other Windows Forms components. Within Visual Studio .NET, ActiveX Controls can be included in the component palette bar and can also be configured using the Properties window. If you prefer using command-line tools, the .NET Framework SDK provides a tool called AXIMP.EXE, known as the ActiveX Control to Windows Forms Assembly Converter, which wraps an ActiveX control into a Windows Forms control (see Figure 11.5).

Figure 11.5. Using Internet Explorer ActiveX controls from Windows forms.

ACTIVEX CONTROLS VERSUS .NET CONTROLS

Even though COM interoperability provides mixing .NET Windows Forms “based applications with ActiveX controls, I would highly recommend discussing the controls with your third-party vendor; chances are that the vendor may have already developed .NET counterparts of those products, and you may also be entitled to them as part of your upgrade contract.


To dive further into this topic, take a look at how an Internet Explorer ActiveX control can be used to develop a simple .NET browser (using Internet Explorer under the covers). This code (Listing 11.2) has been primarily generated through the Visual Studio .NET tool; only the Click() function of the button has been coded to invoke the browser and navigate to the desired URL. Figure 11.6 shows the control.

Listing 11.2 Using Internet Explorer Controls from Windows.Forms
 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace UseIE {    public class Form1 : System.Windows.Forms.Form    {       private System.Windows.Forms.TextBox urlBox;       private System.Windows.Forms.Button goButton;       private AxSHDocVw.AxWebBrowser browser;       private System.ComponentModel.Container components = null;       public Form1()       {          InitializeComponent();       }       protected override void Dispose( bool disposing )       {          if( disposing )          {             if (components != null)              {                components.Dispose();             }          }          base.Dispose( disposing );       }       private void InitializeComponent()       {          System.Resources.ResourceManager resources =              new System.Resources.ResourceManager(typeof(Form1));          this.browser = new AxSHDocVw.AxWebBrowser();          this.urlBox = new System.Windows.Forms.TextBox();          this.goButton = new System.Windows.Forms.Button();          ((System.ComponentModel.ISupportInitialize)(this.browser)).BeginInit();          this.SuspendLayout();          //          // browser          //          this.browser.Enabled = true;          this.browser.Location = new System.Drawing.Point(0, 40);          this.browser.OcxState =           ((System.Windows.Forms.AxHost.State)(resources.GetObject(             "browser.OcxState")));          this.browser.Size = new System.Drawing.Size(376, 264);          this.browser.TabIndex = 0;          //          // urlBox          //          this.urlBox.Location = new System.Drawing.Point(8, 8);          this.urlBox.Name = "urlBox";          this.urlBox.Size = new System.Drawing.Size(288, 20);          this.urlBox.TabIndex = 1;          this.urlBox.Text = "http://www.microsoft.com";          //          // goButton          //          this.goButton.Location = new System.Drawing.Point(312, 8);          this.goButton.Name = "goButton";          this.goButton.Size = new System.Drawing.Size(56, 24);          this.goButton.TabIndex = 2;          this.goButton.Text = "Go";          this.goButton.Click += new System.EventHandler(this.goButton_Click);          //          // Form1          //          this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);          this.ClientSize = new System.Drawing.Size(376, 301);          this.Controls.Add(this.goButton);          this.Controls.Add(this.urlBox);          this.Controls.Add(this.browser);          this.Name = "Form1";          this.Text = "Form1";          this.Load += new System.EventHandler(this.Form1_Load);          ((System.ComponentModel.ISupportInitialize)(this.browser)).EndInit();          this.ResumeLayout(false);       }       [STAThread]       static void Main()        {          Application.Run(new Form1());       }       private void goButton_Click(object sender, System.EventArgs e)       {         String url = urlBox.Text;         Object nullStr = "";         Object nullObj = null;         browser.Navigate(url,ref nullObj,ref nullStr,ref nullStr,ref nullStr);       }    } } 
Figure 11.6. Internet Explorer ActiveX control in a Windows forms application.

Primary Interop Assemblies

If a particular COM object (such as a System COM object) has been used by multiple .NET applications and components, it is quite possible that each development team will end up creating its own Interop Assembly. For such scenarios, a notion of Primary Interop Assembly exists, which can be created by the original COM component developer. The process of primary Interop assembly creation is an advanced interoperability topic and is beyond the scope of this book. I would, however, recommend .NET and COM: The Complete Interoperability Guide by Adam Nathan (ISBN: 0-672-32170-X) as a useful source of information for PIAs and on COM Interoperability in general. Also, the help included with the .NET Framework SDK itself provides further information.



Microsoft.Net Kick Start
Microsoft .NET Kick Start
ISBN: 0672325748
EAN: 2147483647
Year: 2003
Pages: 195
Authors: Hitesh Seth

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net