The HttpServerUtility class provides you with the ability to create late-bound COM objects similar to the way you do in ASP. The methods are CreateObject and CreateObjectFromClsid. They are marked to return a generic Object type. However, the actual type they return is System. ComObject. Objects can be created either from the string representation of the class CLSID or from the progID. The following code creates an instance of a COM component using the CLSID:
Dim strClsid As String strClsid = "42754580-16b7-11ce-80eb-00aa003d7352" Dim comObj As Object comObj = Server.CreateObject(strClsid)
When assigned to a variable declared of type Object, an object is said to be a late bound (as opposed to early bound) strongly typed object. Late-bound objects can hold references to any object, but lack many of the advantages of early-bound objects. Early-bound objects should be used whenever possible because they are significantly faster than late-bound objects and make your code easier to develop, read, and maintain.
Mostly for backward compatibility reasons, you may sometimes happen to create late-bound instances of COM objects. Using COM objects in ASP.NET applications is a common necessity in real-world projects. The best way to import COM functionality in .NET applications entails the use of managed wrappersspecial classes that expose the type library of the COM class as a .NET class. Managed wrappers are usually created by Visual Studio .NET when you reference a COM object in your project.
A command-line utility is also available, should you need to generate the class assembly using a particular namespace, or language or file name different from those automatically set by Visual Studio .NET. The utility is tlbimp.exe and is located in the installation path of the .NET Framework.
Although not especially effective as an approach, the Server.CreateObject method can be used to create a late-bound instance of a COM component. The ideal language for late binding is Visual Basic .NET; however, bear in mind that late binding is supported as long as the Strict option is Off (the default).
The following code shows how to fill an ADO Recordset object using the ASP programming style:
<%@ Page Language="VB" AspCompat="true" %> <script runat="server"> Sub Page_Load(sender as object, e as EventArgs) Dim rs As Object rs = Server.CreateObject("ADODB.Recordset") rs.Open("SELECT firstname, lastname FROM employees", _ "PROVIDER=sqloledb;DATABASE=...;SERVER=...;UID=...;"),<br> Dim sb As StringBuilder = New StringBuilder("") While Not rs.EOF sb.Append(rs.Fields("lastname").Value) sb.Append(", ") sb.Append(rs.Fields("firstname").Value) sb.Append("<br>") rs.MoveNext End While<br> Response.Write(sb.ToString()) End Sub </script>
Note the use of the AspCompat attribute in the @Page directive. Apartment threaded COM components can only be created in ASP.NET pages that have the AspCompat attribute set to True. Before an attempt to create the object is made, the CreateObject method checks the threading model of the component. If the page is already working in ASP compatibility mode-that is, the AspCompat attribute is True-then no matter what the threading model of the component is, the object is created. If the AspCompat attribute is set to False (the default), then CreateObject reads the threading model of the COM component from the registry. If the threading model is apartment, an exception is thrown; otherwise, the object is successfully created.
The use of the AspCompat attribute is not strictly necessary with the ADO library because the ADO library supports both the apartment and the free threading model. COM components developed using Visual Basic 6.0 instead need the AspCompat attribute to be used in ASP.NET pages because they typically use the (single-threaded) apartment model (STA). This situation is detected and throws an exception.
Notice, though, that if your code instantiates the COM object through a managed wrapper (instead of creating the instance using CreateObject) the run time will no longer be able to detect the apartment nature of the component and does not throw an exception. A managed wrapper saves you from a run-time exception, but not from the need of setting AspCompat to True. Running STA components in a multithread apartment environment (MTA) like .NET is strongly discouraged. The page still runs but may incur the typical performance issues that arise when multithreaded clients run STA components. The AspCompat attribute set to True forces ASP.NET to work in STA mode to accommodate the COM object.
Dino Esposito is Wintellect's ADO.NET and XML expert, and a trainer and consultant based in Rome, Italy. Dino is a contributing editor to Windows Developer Magazine and MSDN Magazine, and the author of several books for Microsoft Press including Building Web Solutions with ASP.NET and ADO.NET and Applied XML Programming for .NET. Contact Dino at [email protected].