Integrating .NET with BizTalk
In This Chapter
An Overview of .NET
Integrating .NET and BizTalk Server Orchestration Schedules
Creating a Managed AIC Component
Microsoft BizTalk Server Orchestration and BizTalk Messaging provide a robust set of tools and services that enable developers to automate business and data-exchange processes. These two services, the BizTalk Messaging Engine and XLANG Scheduler Engine, are built on a foundation consisting of COM and COM+, two Microsoft technologies that provide the services necessary to develop highly scalable distributed transactional applications. In July 2000, Microsoft officially announced Microsoft.NET, its next generation development platform and next generation component technology. This chapter discusses how to integrate and develop .NET Application Integration Components (AIC) and BizTalk Orchestration implementation objects.
The chapter begins with a brief conceptual discussion of .NET and the .NET Framework, then follows with a detailed description of the steps required to develop an application that implements a Bank debit and credit transaction using Visual Basic .NET, Visual Studio .NET, and BizTalk Orchestration. After we've created the .NET debit and credit classes, we will test them using a simple ASP.NET Web application and then compile and register them so that they can be accessed from a BizTalk Orchestration schedule. We will also construct a simple C# BizTalk Messaging AIC component that will consume an XML document and then save it to a local file directory.
Note
This chapter assumes a good working knowledge of BizTalk Orchestration and BizTalk Messaging, as covered in Chapter 4, "The BizTalk Editor"; Chapter 5, "The BizTalk Mapper"; Chapter 6, "Introduction to BizTalk Messaging"; Chapter 7, "Using the BizTalk Messaging Manager"; Chapter 9, "Introducing BizTalk Orchestration"; Chapter 10, "Using the BizTalk Orchestration Designer"; and Chapter 11, "XLANG Orchestration Engine," of this book. We also assume that you have been exposed, at least conceptually, to .NET as well as to COM and COM+ programming techniques.
An Overview of .NET
Before discussing how to integrate .NET into a BizTalk application, it's useful to have a conceptual understanding of .NET and the .NET Framework. The main goal of this section is to provide a high-level introduction to .NET and the new Microsoft development platform.
What Is .NET?
Over the last decade, the application development arena has undergone a host of transformations. We've seen the migration of large mainframe green screen applications to Win32 client server applications as well as the introduction and evolution of multitier Web application development. In the past several years, we've also seen the introduction of new and exciting technologies that focus on the integration of applications regardless of the platform and programming language they were developed with. Using Web Services, a technology based on standard transport protocols and data formats such as SOAP (Simple Object Access Protocol) and XML, we can now make platform-agnostic remote procedure calls (RPC) over the Web.
If you've ever tried to build a Web application, you're painfully aware of the complex- ities associated with stateless multitier Web development. Building these types of Web applications, although not rocket science, was and still is time consuming and tedious using traditional development tools. Microsoft .NET is Microsoft's next generation development platform designed to make standards-based Web and Win32 application development much simpler for the developer. It's a radical new way of looking at code development that allows developers to construct applications that can communicate using both traditional and standards-based transport protocols. Some of the new enhancements include the .NET Framework, Common Language Runtime (CLR), Web Services, ASP.NET, and ADO.NET. Visual Studio .NET has also been enhanced to include several new project types, a completely integrated, language-independent development environment, and a new programming language named C#.
By now, it's obvious that .NET introduces many new features, including new form factors, such as Web Forms and Win Forms, and new technologies, such as Web Services and ADO.NET, the next version of ADO. In fact, there are so many new enhancements that it would be impossible to cover them all in a single chapter. So in this chapter we are going to narrow the focus down to the concepts required to create a managed component. Specifically, this chapter introduces the Common Language Runtime (CLR), the .NET Framework, and .NET COM+ services now known as .NET Enterprise Services. Chapter 15, "Web Services and BizTalk Server," discusses .NET Web services.
The .NET Framework
At the foundation of .NET is the .NET Framework. The .NET Framework provides a standards-based, multilanguage environment for integrating existing applications with next generation applications and services. The .NET Framework consists of three main functional areas:
The Common Language Runtime (CLR)
.NET Framework Class Libraries
ASP.NET
The CLR is designed to be a safe and secure managed environment, which means that the CLR automatically manages things such as the memory of an application, hence the term managed code, using a technique known as garbage collection. The runtime also supplies managed code with services such as cross-language integration, code access security, object lifetime management, and debugging and profiling support. Unlike traditional development environments, which require a developer to master multiple frameworks, the CLR also gives developers a single common execution model and object- oriented framework independent of the programming language they are developing in or operating system they are developing for. Figures 14.1 and 14.2 show a high-level diagram of the CLR services and .NET Framework class library.
Figure 14.1 Common Language Runtime architecture diagram.
Figure 14.2 .NET Framework high-level architecture diagram.
To facilitate language and platform interoperability, a .NET language must adhere to two specifications: the Common Language Specification (CLS) and Common Type Specification (CTS). The CLS describes the visible features permitted in a public interface of a .NET class. The CTS defines the .NET types supported. Because the CLR manages the casting of types and marshalling of data between objects, conformance to these specifications by a .NET language permits developers to build applications that inherit objects from one another regardless of the language they are written in.
When compiling managed code, the compiler translates the .NET source code into something known as Microsoft intermediate language (MSIL), a CPU-independent set of instructions that can be converted into native code. At runtime, the MSIL code is converted into CPU-specific code by a just-in-time (JIT) compiler. The Microsoft CLR supplies one or more JIT compilers for each of the platforms it supports. This means that the same MSIL can be JIT compiled and executed on any supported platform. Currently, the CLR is supported on the Microsoft suite of operating system platforms including Windows 2000, 95, 98, and CE. It should also be noted that although the CLR appears to be developed exclusively for the Microsoft suite of operating systems, the list of supported platforms is expected to grow. The CLR specification has been made public and will most likely be ported by third-party organizations to additional operating system platforms in the near future. It is also possible for a developer to create a .NET-compatible language. To create a .NET compatible language, you must construct a language that complies with the CLS and CTS specifications as well as a precompiler that can omit MSIL code. You must also create a JIT compiler that can consume this MSIL code on each of the platforms you want to support. Currently, more than 15 third-party .NET languages are available, including COBOL, Perl, Python, and many more.
The deployment of a component module has also been greatly improved. A managed object's unit of deployment is an assembly. When managed code is compiled, it's converted into MSIL. An assembly is a self-contained unit (similar to a .DLL or .EXE), usually with a .DLL extension, that contains an object's MSIL, its metadata, and its references to any other files. The assembly also contains a manifest. The manifest enumerates the files contained in the assembly as well as the resources and required external references and/or files. This architecture eliminates the need for traditional type libraries and cumbersome registry entries and facilitates XCOPY deployment because an object's metadata is now self-contained. At runtime, the CLR locates and extracts the metadata from the file as needed as opposed to referencing type libraries and registry entries, eradicating DLL hell.
.NET and COM Interoperability
COM differs from the .NET Framework object model in many different areas. To facilitate the coexistence of managed and unmanaged code, the CLR provides two wrapper classes that hide the differences between both, allowing both managed and unmanaged clients to call one another's objects. Whenever your managed client calls a method on a COM object, the runtime creates a Runtime Callable wrapper (RCW). When a COM client references a method on a .NET object, the runtime creates a COM callable wrapper (CCW). Figure 14.3 depicts this process.
Figure 14.3 The COM wrapper overview.
The RCW and CCW wrappers act as proxies between the unmanaged COM code and managed .NET code. The wrappers marshal method arguments and method return values whenever the client and server have different representations of the data passed between them.
The CCW is an unmanaged COM object. It is not garbage-collected and is destroyed when the last client reference is released. After the CCW is destroyed, the managed object that it wraps is also marked for garbage collection. A few of the tasks the CCW is responsible for when a COM component references a managed .NET component include
Managing the lifetime of the .NET component
Creating and binding to the managed object
Translating .NET exceptions into COM HRESULT values
Synthesizing several COM interfaces (IUnknown, IDispatch, and so on) based on the object's type information
Marshalling and translating data between the environments
The RCW is a managed object and is therefore garbage collected by the CLR. A few of its responsibilities include
Managing the lifetime of the wrapped COM object
Creating and binding to the underlying COM object
Translating and marshalling data between environments
Consuming COM interfaces and factoring the interfaces into a managed form
Translating COM HRESULT values into .NET exceptions
To reference a method in a managed class from a COM client, you must first generate a COM type library for the managed object and then register it. There are several ways you can accomplish this in .NET. You can run the type library export command-line utility, tlbexp.exe, to generate a COM type library. However, it will only generate the type library; it will not register it. You could also run the regasm.exe command-line utility. This utility generates a type library and registers it for you automatically. Finally, you can configure Visual Studio .NET to complete both tasks automatically for you at build time by setting attributes in the properties page of a managed class.
Note
The command-line utilities for the .NET Framework are located in the \program files\Microsoft.NET\FrameworkSDK\bin directory on the Visual Studio .NET drive.
In our examples we will create and use both types of wrappers. We will use CCW wrappers in the Bank transaction example to reference the managed bank classes from a BizTalk Orchestration schedule, and both CCW and RCW to develop and reference a managed Application Integration Component (AIC) in the AIC example. We will also depend on Visual Studio .NET to do most of the registration work for us.
The System.EnterpriseServices Namespace
The CLR improves on and is a replacement for COM but not for COM+. COM+ is a runtime environment for objects that provides a set of services intended to make building scalable distributed systems easier by providing a significant portion of the underlying plumbing automatically for the developer. COM+ provides services such as database connection pooling, transaction management, object pooling, queued components, COM+ events, just-in-time activation, and several others so that a developer can focus on the development of the business logic as opposed to the underlying system services.
Like COM, the CLR relies on COM+ to provide runtime services to applications that require them; in fact, it's actually easier to configure COM+ services for the CLR environment than it is for COM. At first glance, you might think that these services are provided through the CLR-COM interoperability layer, which we discussed at length in the previous section. It is possible to use the CLR and associated interoperability wrappers to implement a COM component that uses COM+ services; however, a much more efficient programming model is available.
The CLR can supply COM+ services using an API managed through a namespace called the System.EnterpriseServices. All classes that want to implement COM+ services must extend the ServicedComponent class in that namespace as shown in the following code:
Imports System.EnterpriseServices Namespace BankVB Public Class UpdateBankVB : Inherits ServicedComponent Public Function Credit() As Boolean ... End Class End Namesace
Note
Namespaces are a new concept introduced by the .NET Framework that prevent ambiguity and simplify references when using large groups of class libraries. They also help organize objects defined in an assembly, a .NET component's unit of deployment. To learn more about namespaces and assemblies, refer to the appropriate .NET Framework documentation.
The inheritance from the ServiceComponent class notifies the CLR that instances of this class may require COM+ services. The CLR knows whether an instance of a class requires COM+ services by examining the use of embedded declarative attributes. The System.EnterpriseServices namespace defines a set of attributes that can be used to configure a class's COM+ runtime services.
In traditional COM development, a component's COM+ configuration information was stored in a database known as the COM+ catalog and configured at installation time using either the COM+ Microsoft Management Console (MMC) or a custom script that accessed the catalog directly. In the CLR world, the attributes don't take the place of the COM+ catalog; in fact, during registration, the attributes are evaluated and copied into the COM+ catalog. There is, however, one major distinction. When the CLR calls a managed component that requires COM+ services, it first evaluates the attributes in the code as opposed to the values in the COM+ catalog. Most of the COM+ attributes that we are accustomed to setting administratively are now set declaratively using code with a few exceptions in the role-based security arena. The following code displays how this is accomplished:
Imports System.EnterpriseServices Namespace BankVB <Transaction(TransactionOption.Required)>, __ Public Class UpdateBankVB : Inherits ServicedComponent Public Function Credit() As Boolean ... End Class
Many additional attributes facilitate the control of COM+ services; however, we are going to keep it simple and only focus on two in our example: the transaction and application name attributes. For additional information on the System.EnterpriseServices namespace, refer to the .NET Framework documentation.
After the appropriate configuration attributes are set, the .NET managed object configured class is ready to compile. The CLR COM+ integration layer requires that an assembly be strongly named if an object it contains implements the ServicedComponent interface. To strongly name an assembly, you must generate a strong name using the Strong Name command-line utility, sn.exe, or set the Generate Strong Name property in the properties page of the Visual Basic .NET file in Visual Studio .NET.
After the assembly is created, it's ready to deploy. To deploy a serviced component, you must run the Services Installation command line utility named regsvcs.exe. This utility registers the assembly as a COM component (just as if you had run regasm.exe), creates the COM type library (just as if you had run tlbexp.exe), and then deploys your configured classes to the COM+ catalog, setting the appropriate attributes based on the metadata contained within your configured classes. To enable the COM+ engine to locate your assembly at runtime, you must install the assembly into the Global Assembly Cache (GAC) using the gacutil.exe utility. We will walk through each of these steps in the Bank transaction and C# AIC examples later in this chapter.
Note
Remember that the unit of deployment for a managed object is an assembly that contains all the metadata required to run an object. To run an assembly, either a client must know its exact location or the assembly must be registered in the Global Assemble Cache (GAC). For additional information regarding the GAC, refer to the .NET Framework documentation.