Chapter 1: Introduction to .NET

This chapter introduces the Microsoft® .NET architecture, application security, and .NET XML Framework. It explains the different paths, scenarios, and techniques for migrating a UNIX application to .NET using Visual Studio® .NET 2003. The chapter also discusses the platform differences between UNIX and Microsoft Windows® operating systems and their implementation in .NET.

On This Page

.NET Overview .NET Overview
.NET XML Framework .NET XML Framework
.NET Application Security .NET Application Security
Implementation in .NET Implementation in .NET
.NET Migration Paths .NET Migration Paths
Migration Scenarios Migration Scenarios

.NET Overview

This section provides an overview of the .NET Framework, its components, and their advantages.

The .NET platform is an integral component of the Microsoft Windows operating system for building and running next generation software applications and Web services. The .NET development framework provides a new and simplified model for programming and deploying applications on the Windows platform. It provides such advantages as multiplatform applications, automatic resource management, and simplification of application deployment. As security is an essential part of .NET, it provides security support, such as code authenticity check, resources access authorizations, declarative and imperative security, and cryptographic security methods for embedding into the user’s application.

.NET provides a simple object-oriented model to access most of the Windows application programming interfaces (APIs). It also provides mechanisms by which you can use the existing native code. In addition, it significantly extends the development platform by providing tools and technologies to develop Internet-based distributed applications.

The .NET Platform

The Microsoft .NET platform, as illustrated in Figure 1.1 and described as follows, consists of four components:

  • .NET Framework. The .NET Framework is a multilanguage, application execution environment that transparently manages core infrastructure services. It is a set of multiple languages/technologies used for developing and creating components to create Web Forms, Web services, and Windows applications. It supports the software life cycle for development, debugging, deployment, and maintenance of applications. The version of .NET framework that ships with Visual Studio .NET 2003 is version 1.1. The .NET Framework consists of the following parts (also depicted in Figure 1.2):

    • Common Language Runtime (CLR).

    • .NET Framework base class library.

    • Common Language Specification (CLS).

    • .NET-compliant languages.

    • Data and XML classes such as ADO.NET and XML.

    • A set of class libraries for building XML Web services.

    • ASP.NET Web Forms-based Web applications.

    • Windows Forms-based rich client applications.

    • Common Type System (CTS).

    • Microsoft Visual Studio .NET 2003 integrated development environment (IDE).

  • Development tools. Microsoft provides the programming model, the development environment, and the tools necessary to build, deploy, and operate Web services with applications such as Visual Studio .NET 2003.

  • .NET enterprise servers. The Microsoft .NET enterprise servers make up the Microsoft .NET server infrastructure for deploying, managing, and operating XML Web services and traditional applications. Examples of enterprise servers are Microsoft SQL Server™ 2000 and Microsoft Commerce Server 2000.

  • .NET foundation services. A core set of building block services that execute standard tasks and act as a basis for developers to build upon. These foundation services are known as Microsoft .NET My Services and provide many features and functions. Most of the foundation services are hosted (outsourced) services. An example of a currently available Web service is Microsoft .NET Passport.

Figure 1.1. The .NET Framework overview

Figure 1.1. The .NET Framework overview

Advantages of .NET

The .NET Framework provides the following advantages:

  • A consistent, object-oriented programming environment.

  • A code-execution environment that:

    • Promotes safe execution of code.

    • Eliminates the performance problems of scripted or interpreted environments.

    • Minimizes software deployment and versioning conflicts.

  • A consistent experience for both developers and users across various types of Windows-based and Web-based applications on multiple devices.

  • Communication built on the industry standards to ensure that code based on the .NET Framework can integrate with any other code.

.NET is based on open Internet standards, which include Hypertext Transfer Protocol (HTTP), Extensible Markup Language (XML), and Simple Object Access Protocol (SOAP).

Note   More information on XML is available at https://msdn.microsoft.com/xml/ .
More information on SOAP is available at
https://msdn.microsoft.com/library/en-us/dnsoap/html/understandsoap.asp.

Figure 1.2 depicts the overall architecture of the .NET Framework components.

Figure 1.2. The .NET Framework architecture

Figure 1.2. The .NET Framework architecture

Features of the .NET Framework

This section discusses some of the features of the Microsoft .NET Framework and how to use these features in migrating code from the UNIX environment.

Common Language Runtime (CLR)

The core of the .NET Framework is the CLR, the run-time environment provided by .NET. The runtime manages code at execution time and provides core services such as memory management, thread management, remoting, and strict type safety enforcement.

Figure 1.3 depicts the components of CLR.

Figure 1.3. CLR components

Figure 1.3. CLR components

CLR Features

UNIX applications, redeveloped on .NET, can make use of all the features provided by the CLR, including:

  • Simplified development and deployment of applications.

  • Application memory management.

  • Improved performance, scalability, and reliability.

  • Cross-language inheritance.

  • Multiple language support.

  • Automatic garbage collection.

  • Security.

  • Strong type checking.

  • Access to type metadata.

  • Unified exception handling.

  • Interoperability with existing code in COM (Component Object Model) objects and Microsoft Win32® DLLs.

  • Loading and executing code.

  • Just-in-time (JIT) compilation of Microsoft intermediate language (MSIL) to native code.

  • Side-by-side execution for multiple assembly versions.

  • Other developer support services that include debugging and run-time profiling.

  • Versioning and deployment support.

The .NET runtime also enforces other forms of controlled code access that promote security and robustness. Code management is a fundamental principle of the runtime. Code that targets the CLR is known as managed code, whereas code that does not target the CLR is known as unmanaged code. Unmanaged code can also be used in the .NET environment using interoperability techniques as explained in Chapter 3, “.NET Interoperability” of this volume.

All .NET applications compile to a common language called MSIL. A JIT compiler then compiles MSIL to optimized native code.

Benefits of CLR

This various benefits offered by the CLR are as follows.

Security

The runtime enforces code access security. The managed components have varied degrees of trust level depending on a number of factors, including their origin. Even if the same active application is using the managed component, depending on the trust level, the managed component might or might not be capable of performing file-access operations, registry-access operations, or other sensitive functions.

For example, users can trust that an executable embedded in a Web page can play an animation or a song, but cannot access their personal data, file system, or network.

Code Robustness

The runtime also enforces code robustness by implementing a strict type-and-code-verification infrastructure called the Common Type System (CTS). The CTS ensures that all managed code is self-descriptive. The various Microsoft and third-party language compilers generate managed code that conforms to the CTS.

Developer Productivity

The runtime also accelerates developer productivity by enabling the developers to write applications in the development language of their choice and still take advantage of all the features of the runtime. The language compilers that target the .NET Framework make the features of the .NET Framework available to the existing code written in that language, thus greatly facilitating the migration process for the existing applications.

Performance

The runtime is designed to enhance performance. JIT compiling enables all managed code to run in the native code of the system on which it is executed. At the same time, the memory manager removes the possibilities of fragmented memory and increases the memory locality-of-reference to improve the performance further.

Interoperability

The runtime, although designed for modern software, also offers backward compatibility by supporting older software. Interoperability between managed and unmanaged code provides seamless integration to developers to continue to use necessary COM objects and exported functions in unmanaged DLLs.

.NET Framework Base Class Library

The Microsoft .NET Framework 1.1 base class library is an object-oriented class library providing an integrated set of classes that expose the underlying functionality of the Win32 API as well as some other additional capabilities. These classes integrate tightly with the CLR. Third-party components can also integrate with the classes in the .NET Framework. In Microsoft .NET library, all class (types) are grouped in namespaces. A namespace is a grouping of similar kinds of classes.

The .NET Framework classes enable you to perform a range of common programming tasks such as string management, data collection, database connectivity, and file access. In addition to these common tasks, the class library includes classes that support a variety of specialized development functions. For example, you can use the .NET Framework to develop a variety of applications such as console applications, GUI (graphic user interface) applications, and Web applications.

All .NET languages can use these language-independent classes. This enables the programmers to choose the language and tools best suited for the job or the language with which they have the most experience and still share their code and create new subclasses from classes written in a different language. This code reuse can dramatically increase team productivity and decrease development costs. Figure 1.4 depicts some of the namespaces and their classes in the .NET Framework.

Figure 1.4. The .NET Framework base class library

Figure 1.4. The .NET Framework base class library

.NET Tools and Technologies

From a migration perspective, .NET provides various tools and technologies that help you to migrate or redevelop a UNIX application on Windows. Some of these tools and technologies are discussed in the following sections.

Database - ADO.NET

.NET provides ADO.NET for migrating the database-related components of a UNIX application to .NET. ADO.NET is a collection of classes, structures, and interfaces that manage the data access for different databases. .NET provides this data access technology to enable you to connect to different databases including ODBC-aware (open database connectivity) databases.

Networking - System.NET

The System.NET namespace in .NET allows you to replicate the networking functionality of a UNIX application on Windows.

Transaction - COM+ Services

.NET provides COM+ services, also referred to as Enterprise Services in .NET, to migrate applications that involve large amount of transactions.

Rich Client - Windows Forms

Windows Forms enable you to replicate the X/Motif-based GUI of a UNIX application on Windows. Windows Forms facilitate building of Windows rich-client applications that take advantage of the CLR. The Visual Studio .NET 2003 IDE also aids in the rapid redevelopment of GUI on Windows with the same look and feel as in UNIX.

Web Applications - ASP.NET

.NET provides Web Forms and ASP.NET for migrating the existing Web application on UNIX to Windows. Web Forms and ASP.NET enable you to develop real-world Web applications on Windows.

Application Integration - XML, SOAP, and Web Services

.NET supports XML, SOAP, Web services, and .NET servers that enable a migrated application to integrate with the older applications and other applications in your enterprise.

.NET XML Framework

This section lists the XML APIs available in the .NET class library that you can use for various XML-related operations.

XML is truly a core technology substrate in .NET. All other parts of the .NET Framework (such as ASP .NET and Web services) use XML as their native data representation format. The .NET Framework XML classes are also tightly coupled with Managed Data Access (ADO .NET). Traditionally, there have always been different programming models for working with relational and hierarchical data. .NET breaks that tradition by offering a more deeply integrated programming model for all types of data.

New Suite of XML APIs

Microsoft .NET introduces a new suite of XML APIs built on such industry standards as Document Object Model (DOM), XPath, XML Structured Definitions (XSD), and Extensible Stylesheet Language Transformations (XSLT). The .NET Framework XML classes offer convenience and better performance. The .NET XML Framework also provides a more familiar programming model, tightly coupled with the various classes present in System.Data and System.Xml namespaces, which encapsulate a number of functionalities that previously had to be accomplished manually.

.NET XML Namespaces

The System.Xml assembly contains a broad range of general-purpose XML support features, such as:

  • Basic I/O model.

  • I/O of primitive types.

  • In-memory traversal.

  • Filtering based on XPath expressions.

  • Transformations based on XSLT.

The .NET XML stack is partitioned over several namespaces, such as:

  • System.Xml.XPath

  • System.Xml.Xsl

  • System.Xml.Schema

  • System.Xml.Serialization

XML-based I/O

All XML-based I/O is performed using a streaming interface suite as follows:

  • Streams are supported in both pull-mode (read) and push-mode (write).

  • Built-in streaming adapters use the System.IO.Stream class library.

  • Abstract interfaces allow you to provide your own XML providers/consumers.

.NET DOM Implementation

The .NET DOM implementation (System.Xml.XmlDocument) supports all W3C DOM Level 1 core and all DOM Level 2 core specifications, but with a few minor naming changes. The DOM loading is built on top of XmlReader, while the DOM serialization is built on XmlWriter. This makes it possible to extend how the DOM interacts with applications in numerous ways.

Note More information on W3C DOM Level 1 core and Level 2 core specifications is available at https://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/ and https://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/.

Transformations

The XslTransform class manages XSLT transformations in the .NET Framework. XslTransform resides in the System.Xml.Xsl namespace and uses XmlNavigator during the transformation process. As with all XSLT processors, XslTransform accepts an XML document, an XSLT document, and some optional parameters as input. It can produce any type of text-based output; it also supports reading the result of the transformation using a custom XmlReader.

.NET Application Security

This section provides an overview of various security models available in the .NET Framework. The .NET Framework provides a rich security system, capable of confining code to run in a tightly constrained, administrator-defined, security context.

Role-based Security

The .NET Framework provides a developer-defined security model called role-based security that attaches security to the users and their groups (or roles). The principal abstractions of role-based security are principal and identity.

Code Access Security

Additionally, the .NET Framework also provides security on code, referred to as code access security (also referred to as evidence-based security). With code access security, a user may be trusted to access a resource but if the code that the user executes is not trusted, then access to the resource is denied. Code access security also provides a highly protective way of securing the assemblies from malicious attacks. Security based on code, as opposed to specific user, is a fundamental facility that permits security to be expressed on mobile code. Any number of users may download and execute mobile code, which is unknown at the time of development. Code access security focuses on some core abstractions, namely, evidence, policies, and permissions.

The security abstractions for role-based security and code access security are represented as types in the .NET Framework class library and are user-extendable.

The .NET Framework security system functions atop the traditional operating system security. This adds a second, more expressive and extensible level to the operating system’s security. Both layers complement each other. (It is conceivable that an operating system security system can delegate some responsibility to the CLR security system for managed code because the run-time security system is more configurable then the traditional operating system security.)

Note   More information on .NET Framework security is available at https://msdn.microsoft.com/security/securecode/dotnet/default.aspx.

Implementation in .NET

Chapter 1, “Introduction to Win32/Win64” of Volume 3 has already discussed the platform differences between UNIX and Windows from various aspects. The following topics give an overview for implementing the following architectural elements in .NET:

  • Processes and threads

  • Memory management

  • File management

  • Signals, exceptions, and events

  • Networking

  • Interprocess communication

  • User interface

  • Daemons versus services

  • Deployment

Processes and Threads

The .NET Framework further divides an operating system process into lightweight managed subprocesses, called application domains, which provide a versatile unit of processing in .NET applications. These application domains are used to provide isolation between applications and even within a single process. Several application domains can be run in a single process with the same level of isolation that would exist in separate processes. Historically, process boundaries have been used to provide isolation between applications, but application domains provide a level of isolation equivalent to that of a process boundary, however at a much lower cost of performance.

The System.Threading namespace in .NET provides all the classes and interfaces necessary to enable multithreaded programming. In addition to classes for synchronizing thread activities and providing access to data (for example, Mutex, Monitor, Interlocked, and AutoResetEvent), this namespace includes a ThreadPool class that allows use of a pool of system-supplied threads and a Timer class that executes callback methods on the thread pool threads. The next chapters discuss application domains and the threading namespaces in detail.

Memory Management

The garbage collector of the .NET Framework provides automatic memory management. It allocates and releases the memory for managed objects and, when necessary, executes the appropriate methods at the appropriate times in order to properly clean up the unmanaged resources. Automatic memory management simplifies development by eliminating the common bugs that arise from manual memory management schemes.

File Management

In .NET, the System.IO namespace provides an object-oriented tool to work with files and folders. It provides a collection of properties, methods, and events to process text and data, thus enabling you to perform file and directory operations with greater ease. For more information on the System.IO namespace, refer to Chapter 4, “Memory and File Management” of this volume.

Signals, Exceptions, and Events

.NET Framework provides an event handler mechanism to handle events. An event handler is a procedure in your code that determines the actions that must be performed when an event (such as the user clicking a button or a message queue receiving a message) occurs. When an event is raised, the event handler (or a handler) that receives the event is executed. Events can be assigned to multiple handlers and the method that handles a particular event can be changed dynamically.

The .NET Framework handles exceptions through the exception handling mechanism. In the .NET Framework, an exception is an object that it inherits from the System.Exception class. An exception originates from an area of code where a problem occurred. The exception is passed up the stack until the application handles it or the program terminates. All .NET languages handle exceptions in a similar manner. Each language uses a form of try/catch/finally structured exception handling.

Networking

The .NET Framework class library includes two namespaces that consists of classes that help you with networking; these are System.Net and System.Net.Sockets.

The System.Net classes provide a simple, yet complete solution for writing networked applications in managed code. The System.Net.Sockets classes deals with the TCP/UDP and sockets.

Interprocess Communication

In the .NET environment, application domains enable more than one application to run within a single process, thus eliminating the overhead of making cross-process calls but still maintaining the same level of application isolation that would exist in separate processes. .NET also supports the concept of thread local storage, by which data can be stored in a thread and accessed anywhere the thread exists.

Microsoft .NET Remoting provides a rich and extensible framework for objects residing in different application domains, in different processes, and in different computers to communicate with each other seamlessly. .NET Remoting offers a powerful, yet simple, programming model and run-time support for making these interactions transparent.

User Interface

In the .NET environment, user interfaces can be developed as Windows or Web Forms. Some of the advantages of using these forms include the following:

  • Simplicity and power

  • Rich graphics

  • Flexible controls

  • Lower total cost of ownership

  • Architecture for controls

  • High security

  • XML Web services support

  • Data awareness

  • ActiveX control support

  • Easy licensing

  • Enhanced printing support

  • Accessibility

  • Design-time support

Daemons vs. Services

The .NET Framework class library includes the System.ServiceProcess namespace that provides classes to implement, install, and control Windows service applications.

Services are installed using an installation tool, such as InstallUtil.exe. The System.ServiceProcess namespace provides installation classes that write service information to the registry.

The ServiceController class enables you to connect to an existing service and manipulate it or get information about it. This class is typically used in an administrative capacity; it enables you to start, stop, pause, continue, or perform custom commands on a service.

Deployment

In .NET Framework applications, assemblies are the building blocks. They form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions. Current Win32 applications have two versioning problems with their building blocks (dynamic-link libraries):

  • Versioning rules cannot be expressed between pieces of an application and enforced by the operating system.

  • Inability to maintain consistency between sets of components that are built together and the set that is present at runtime.

These two versioning problems combine to create DLL conflicts, or DLL Hell, where installing one application can inadvertently break an existing application because a certain software component or DLL that was installed was not fully backward compatible with a previous version. The CLR uses assemblies to provide a complete solution for DLL conflicts. Assemblies allow the runtime to:

  • Enable developers to specify version rules between different software components.

  • Enable the infrastructure to enforce versioning rules.

  • Enable the infrastructure to allow multiple versions of a component to run simultaneously (called side-by-side execution).

Each computer, where the CLR is installed, has a machine-wide code cache called the Global Assembly Cache (GAC). The GAC stores assemblies specifically designated to be shared by several applications on the computer.

Assemblies deployed in the GAC must have a strong name. When an assembly is added to the GAC, integrity checks are performed on all files that make up the assembly. The cache performs these integrity checks to ensure that an assembly has not been tampered with.

Summary of Platform Differences

Table 1.1 lists the basic platform differences that exist between UNIX, Windows, and .NET.

Table 1.1. Summary of Platform Differences

Architectural Element

UNIX

Windows

.NET

Processes

Processes have a parent-child relationship.

Process boundary provides isolation between applications.

Processes do not have a parent-child relationship.

Process boundary provides isolation between applications.

Processes do not have a parent-child relationship.

An operating system process is further divided into subprocesses called application domains. Application domains provide isolation between applications.

Threads

UNIX threads are built upon the POSIX standard, known as Pthreads.

The Windows operating system provides built-in support for threads and thread synchronization using Platform SDK.

.NET provides the System.Threading namespace to support multithreading in conjunction with Windows threads.

Memory

At application level, memory management is manual (in the hands of the programmer).

At application level, memory management is manual (in the hands of the programmer).

Memory management is automatic and controlled by the CLR, eliminating bugs such as memory leakages from manual memory management.

File

File operations are performed through low-level I/O functions and stream I/O functions.

File operations are performed through low-level I/O functions and stream I/O functions.

The System.IO namespace provides an object-oriented framework for handling files and folders.

Signals

UNIX supports a wide range of signals. Signals are software interrupts that catch or indicate different types of events.

Windows supports only a small set of signals that is restricted to exception events. Native signals, event objects, and messages are the recommended mechanisms to replace common UNIX signals.

.NET does not support signals.

Events and exception handling mechanisms in .NET are the recommended mechanisms to replace common UNIX signals.

Networking

UNIX supports networking through sockets.

In Windows, sockets are implemented using WinSock libraries.

The System.Net.Sockets namespace provides networking support in .NET.

Interprocess communication

UNIX provides shared memory, pipes, and message queues for interprocess communication.

Windows provides shared memory, pipes, events, Dynamic Data Exchange (DDE), Component Object Model (COM), and mailslots for interprocess communication.

.NET Framework provides .NET Remoting and Microsoft Message Queue for interprocess communication.

UI differences

UI is developed using X Windows and Motif, which are the standard windowing system and windowing system library respectively on UNIX.

UI is developed using MFC (Microsoft Foundation Classes), ATL (Active Template Library), or GDI+ (Graphics Device Interface).

.NET Framework provides Windows Forms and Web Forms for development of UI of rich client and Web applications respectively.

Deployment differences

UNIX provides shared objects for developers to group common functionality and deploy them.

Windows provides DLLs for developers to group common functionality and deploy them.

In .NET, assemblies form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions.

Daemons and services

UNIX supports daemons (a process that runs in the background and does not require a user interface).

Windows service is the equivalent of daemons.

.NET provides the System.ServiceProcess namespace to implement, install, and control Windows service applications.

.NET Migration Paths

This section discusses the various .NET migration paths. You can use this information in reengineering code in .NET and in understanding the interaction of the .NET code with existing applications. This section also helps you to choose the best migration path based on the nature of existing UNIX applications.

To move UNIX applications to the Microsoft .NET Framework, you need to migrate the existing UNIX C or C++ code to Windows. For example, if the UNIX applications use third-party libraries and if the equivalents of such third-party libraries are already available on Windows, then the UNIX to Windows move is much easier. The code migrated from UNIX can then integrate the .NET Framework features.

For UNIX applications involving code in Java, Visual Studio .NET 2003 provides a tool known as Java Language Conversion Assistant (JLCA) that can automatically convert existing Java language code into C#. You can use this tool in migration scenarios where the existing UNIX application contains Java code.

With a large code base of installed UNIX applications, you are unlikely to relish the thought of throwing out the entire environment and starting again with an unfamiliar platform. Fortunately, you do not necessarily have to do this. As illustrated in this guide, methods are available by which you can preserve the existing code while moving to .NET.

Analyzing Application Types

The application type and the ease with which you can move the application from UNIX to Windows should decide whether to use the .NET interoperability strategies or to redevelop the application completely on the .NET environment. Different application types and strategies for migrating these application types are discussed in the following sections.

Static Application

Static applications are applications that are in the later stages of their life cycle, with stable code, and with little or no changes planned. If these applications can be migrated to Win32 using little or no code changes, then they can also be adapted to make use of the capabilities of the .NET platform by using the interoperability services provided by .NET. This way you can not only speed the application migration but also preserve your investments in the existing code. If the static application is an enterprise application, such as a portal or a content management system, then you can take advantage of the capabilities of the .NET servers, in addition to reusing the existing code.

Evolving Application

Evolving applications are applications that are constantly being changed and enhanced. An evolving application typically contains both static and dynamic components. Static components are the parts of the application that do not change, whereas dynamic components are the parts of the application that are evolving.

First, identify the static and dynamic components of the application and then use the .NET interoperability strategies to migrate the static components.

The dynamic components can be redeveloped in .NET targeting the benefits offered by the CLR and making full use of the other benefits of the .NET development platform.

Table 1.2 lists the .NET migration strategies for the different types of applications.

Table 1.2. Migration Strategies

Application

Nature of Existing Application

Recommended Solution

Static application

Native UNIX application (UNIX APIs, X Windows, and Motif).

Migrate the application to Win32/Win64 with minor code changes and then interoperate with the .NET code to preserve and make use of the investments made earlier.

Static application

Enterprise applications such as portal, content management, and others.

Use .NET servers and interoperate with the migrated Win32/Win64 or unmanaged code.

Evolving application

Native UNIX application (Unix APIs, X Windows, and Motif).

Reengineer in .NET

Evolving application

Enterprise applications such as portal, content management, and others.

Use .NET servers; interoperate with the migrated Win32/Win64 or unmanaged code, and reengineer in .NET.

The subsequent sections discuss the different migration strategies listed in Table 1.2.

  • Reengineering using the .NET Framework.

  • Interoperating with the existing code.

  • Utilizing .NET servers.

Reengineering Using the .NET Framework

This section describes reengineering the applications using the .NET Framework and its advantages. A reengineering strategy is appropriate when an application needs to evolve further and the costs of porting the application outweigh the benefits, or when specific application qualities (such as performance or scalability) require that the code be written specifically for the Windows platform.

Rewriting an application has a number of significant advantages, including:

  • Code robustness.

  • Accelerates developer productivity.

  • Enhanced performance and scalability.

  • Interoperability between managed code and unmanaged code.

  • Flexible language options.

  • Improved tool support.

  • Rich class library.

You can redevelop an application using any of the .NET compatible languages, such as Microsoft Visual Basic® .NET, C#, and Managed C++. Managed code, which is compiled to Intermediate Language (IL) and not to machine code, is created using these languages. The redeveloped code on .NET can make use of all the features of the CLR. The code that is redeveloped in .NET to target the CLR goes through the managed execution process. The following steps are involved in the managed execution process.

  1. Choose a compiler.

    To obtain the benefits provided by the CLR, you must use one or more language compilers that target the runtime, such as C#, Microsoft Visual C++®, Microsoft Visual Basic .NET, Microsoft Visual J#®, Microsoft JScript®, or one of the many third-party compilers such as Eiffel, Perl, or COBOL. Multiple .NET languages support a common set of data types. For example, a string in C# is the same data type as a string in Visual Basic .NET. If you are migrating a C++ application, consider using the Visual C++ .NET for redevelopment. If you are migrating a Java application, you can consider Visual C# for redevelopment.

  2. Compile code.

    On compiling the code, it is converted to Microsoft Intermediate Language (MSIL) code using the selected .NET language compiler. When you execute the code for the first time, the Just-In-Time (JIT) compiler translates MSIL into the native code. During this compilation, code must pass a verification process that examines MSIL and the metadata to find out whether the code can be determined to be type safe. There are two kinds of JIT compilers: Standard JIT and Econo-JIT. Econo-JIT has a faster compilation speed and a lesser compiler overhead than Standard-JIT. However, the Standard-JIT generates more optimized code than the Econo-JIT and includes the verification of MSIL code.

  3. Execute code.

    The CLR provides the infrastructure for executing the code as well as a variety of services that can be used during execution.

Figure 1.5 illustrates the managed execution process in a .NET application.

Figure 1.5. Managed execution process

Figure 1.5. Managed execution process

Reengineering is a costly and time-consuming option. This strategy requires a thorough analysis of the UNIX application functionality before redesigning a .NET-based application architecture. This ensures that the rewrite of the UNIX code takes full advantage of the .NET platform and the Windows application platform. This strategy has a great risk, but it also can produce the best results.

Interoperating with the Existing Code

This section discusses interoperating with existing code and outlines the various interoperability techniques. With the help of the instructions provided in this section, you can choose the interoperability technique that is best suited for your UNIX application.

In the interoperate strategy, the application is migrated with the minimum necessary changes to the source code, using UNIX-compatible libraries and tools that are available on the Windows platform (and which can include Microsoft Interix). The migrated code may require significant changes to enable the code to run on the new platform if the original code is not fully standards-compliant or if the code elements (for example, device drivers) are specific to the original system.

Reasons for choosing to port an application directly to Windows are as follows:

  • Rewriting the code from scratch is costly or time consuming.

  • A large amount of source code already exists.

  • The application requires cross-platform support.

  • The application uses a large number of UNIX APIs.

As long as the application functionality is tightly controlled, the interoperate strategy reduces the risk of negatively altering the application by preserving the business logic, as well as reducing the need for new documentation.

Unmanaged code is the code that runs outside the CLR. Unmanaged code compiles directly to machine code, which runs on the computer where you compile the code and on other computers, as long as the other computers have the same chip or are nearly the same. Unmanaged code does not get services, such as security or memory management, from an invisible runtime; it gets these services from the operating system.

.NET provides interoperability with unmanaged code in the following ways:

  • Managed Extensions for C++

  • .NET Interoperability services

    • C++ Interoperability (It Just Works)

    • Platform Invocation services (P/Invoke)

    • COM Interoperability services

The following sections describe these interoperability techniques in detail.

Managed Extensions for C++

Managed Extensions for C++ provide a systematic methodology for wrapping of the existing unmanaged C++ classes. This enables use of the unmanaged code from the managed applications. In this method, a managed wrapper class for the existing C++ unmanaged class is created. This wrapper class interoperates with its unmanaged equivalent and, in essence, acts as a proxy for accessing the unmanaged class.

For example, if the UNIX application to be migrated is a high-performance application, then C++ wrappers can be used because they offer the following advantages:

  • Single level of wrapping. In COM interoperability, there are two levels of wrapping: one at the COM level and another at the RCW (runtime callable wrapper) level.

  • Limited wrapping. Member functions accessed from the managed code/application only need to be wrapped.

  • Data marshalling. Fine-tuned data marshalling.

However, the disadvantage in using C++ wrappers is that it involves more coding because you need to wrap the unmanaged class, its constructors, destructors, and member functions.

For more information on wrapping unmanaged classes with Managed Extensions for C++, refer to Chapter 2, “.NET Interoperability” of this volume.

.NET Interoperability Services

.NET provides the following services for interoperability with unmanaged code:

  • Platform Invocation services (P/Invoke)

  • C++ Interoperability (It Just Works)

  • COM Interoperability services

These topics are explained along with examples in Chapter 3, “.NET Interoperability” of this volume.

Platform Invocation Services (P/Invoke)

Platform Invocation services (P/Invoke) enable the managed code to call the C-style functions, which are exposed by the native dynamic-link libraries (DLLs). P/Invoke services provide a direct way of using the C functions from the existing native DLLs in a managed application. P/Invoke services are used in conjunction with the DllImport attribute, which is used to import functions from an unmanaged DLL into a managed application.

As an example, consider a situation where the UNIX code can be migrated to Windows with minimal changes and you need to use this code in a new C# or Visual Basic .NET application or project. After migrating to Windows, you can compile the code into a DLL and call it from any .NET project.

This method provides the following advantages:

  • Usage. You can use this method with all .NET languages (C#, Visual Basic .NET, and Managed Extensions for C++). Therefore, new C# or Visual Basic .NET projects can use the DLLImport attribute to connect to the unmanaged code.

  • Quick reuse of code. This method enables quick reuse of the existing native code.

However, you may not use this method in the following situation: If a function in the DLL returns an unmanaged string, such as

Note: The line has been split into multiple lines for readability.However, while trying it out on a system you must enter it as one line without breaks.

[DllImport("mylib")]
extern "C" String * MakeSpecial([MarshalAs
(UnmanagedType::LPStr)] String *);

then you will not be able to delete the memory of the unmanaged string that is returned. In such cases, the C++ Interoperability It Just Works (IJW) method described in the next section is the best choice.

The disadvantages of the P/Invoke method are:

  • Used with attribute only. Unmanaged APIs cannot be used directly without the use of the DLLImport attribute.

  • Memory leakage. This method sometimes causes memory leakages for some C-style functions using unmanaged data types as illustrated by the earlier example.

C++ Interoperability (It Just Works)

This is a platform invocation service, available only in Managed C++, which is designed for using the unmanaged APIs directly without using the DLLImport attribute.

When the UNIX code can be migrated to Windows with minimal changes, then this code can also be compiled in a .NET-managed C++ project using the /CLR switch for the compiler.

This method offers the following advantages:

  • No memory leakage. Memory leakages, such as the one shown in P/Invoke with the DLLImport attribute, do not occur.

  • Can be used directly with unmanaged APIs. Use the unmanaged APIs directly.

  • Faster execution.This method is slightly faster. For example, the IJW stubs do not need to check for the pin or copy data items as the developer does that explicitly.

  • Better performance. For example, if you need to call several unmanaged APIs using the same data, marshaling all APIs once up front and passing the marshaled copy around is much more efficient than remarshaling APIs every time.

  • Reuse marshaled data. This method provides the capability to marshal the data once and reuse the marshaled data at multiple call sites, thereby amortizing the cost of the marshaling.

  • Quick reuse of code. This method enables quick reuse of the existing native code.

The disadvantages of this method are:

  • Used with C++ language. This method can be used only with the C++ programming language (although the interop can be used with any language).

  • Pointer calls required. Specify explicit marshalling in the code, which means extra pointer calls are necessary.

COM Interoperability Services

The .NET Framework has made provisions for interoperability by implementing various wrappers for COM objects to allow exposure of their properties and methods to .NET components. These wrappers make it easy to make the connection between COM and .NET.

For example, if there is a piece of common code that can be migrated to Windows with minimal changes and is to be reused across many applications in an enterprise, you can create a COM component. This COM component can be used in other applications as well as a .NET application. However, as this method involves creating a COM component over the code migrated from UNIX, it is least used in UNIX migration scenarios.

Some of the advantages offered by COM Interop services are:

  • Used with all COM-enabled languages. Any COM-enabled language can use COM, which is a well-understood interface.

  • Marshaling. COM supports marshaling, although COM objects reside in separate processes or address spaces or even different computers. The operating system takes care of marshaling the call and calling objects running in a different application (or address space) on a different computer.

  • Consistency. Maintains the consistency of the programming model.

  • Bridge. Provides the bridge between COM and runtime.

For example, a C++ code in UNIX that can run on Windows with minimal changes can interact with a Visual Basic application that already exists in the Windows platform and the .NET application on different computers using COM.

Other situations where you can select COM interoperability are:

  • Code in UNIX exists. A large amount of UNIX code, which you can make a COM component with minimal changes.

  • Cross-platform libraries. If the code in UNIX makes extensive use of third-party libraries that are available in Win32, but not in .NET, you can make this code as a COM component and access the COM component in .NET applications.

  • Application defined in layers. If the application is defined in layers and one of the layers interacts with the system level APIs, which need minimal changes to migrate to Windows, the components of this layer can be made as COM components and access the COM components in .NET applications.

However, this method’s performance is low as it involves two levels of wrapping (the COM interface and RCW).

Performance Considerations

The interoperability strategies discussed earlier involve data marshaling. For example, the strings in the native code may use the ANSI format. These strings are not compliant with the CLS and so you cannot use them directly with other .NET Framework-compliant languages. The CLR supports Unicode string format. Converting between the two formats requires data marshalling, which creates an additional overhead. However, there is no marshaling cost when converting between blittable types. Blittable types have the same representation in managed and unmanaged code. For example, there is no cost for converting between int and Int32.

The P/Invoke services have an overhead of between 10–30 x86 instructions per call. In addition to this fixed cost, marshaling results in additional overhead. For higher performance, it may be necessary to have fewer P/Invoke calls that marshal as much data as possible instead of having more calls that marshal less data per call.

Utilizing .NET Servers

.NET incorporates the .NET enterprise servers, including the Microsoft Application Center, Microsoft Commerce Server, Microsoft Host Integration Server, Microsoft Internet Security and Acceleration Server, Microsoft Mobile Information Server, Microsoft SharePoint® Portal Server, Microsoft BizTalk® Server, Microsoft SQL Server™, and Microsoft Exchange Server. These servers support the .NET Framework and provide powerful back-office services on which you can build and run .NET applications.

.NET enterprise servers are integrated tightly with the Windows and COM, and they provide enhanced performance and capabilities for the existing Windows applications and architectures. The .NET enterprise servers are XML-enabled so that they also provide a comprehensive set of services for building applications and enterprise solutions on the new .NET Framework.

For example, an enterprise application in a UNIX environment can be migrated to the Windows environment by using the BizTalk Server. You can write pipeline components in .NET using any of the .NET languages, which you can refer in BizTalk Server applications for creating custom pipelines. The groups of .NET enterprise servers have been renamed as the Windows Server System.

Note More information on .NET servers is available at https://www.microsoft.com/windowsserversystem/products/default.mspx.

Migration Scenarios

This section describes the different categories of applications that are migrated, such as rich client applications, Web applications, and database applications. For each of these categories, it discusses the various techniques involved in migration.

Rich Client Applications

The majority of UNIX graphical interfaces are built on X Windows and Motif. The main user interface type in use on the UNIX platform today builds on the X Windows set of standards, protocols, and libraries.

.NET provides Windows Forms for migrating the GUI of rich client applications built on X Windows to the Microsoft Windows operating system. Windows Forms is a framework for building Windows client applications that uses the CLR. This framework provides a clear, object-oriented, extensible set of classes that enable you to develop rich Windows applications. You can write Windows Forms applications in any language that the CLR supports. Using Visual Studio.NET 2003 enables you to visually design Windows Forms, use the familiar drag-and-drop double-click techniques, and enjoy full-fledged code support including statement completion and color-coding. This enables developers to reengineer an application rapidly.

The application-programming model for Windows Forms consists of forms, controls, and their events.

  • Forms. In Windows, the Form class is a representation of any window displayed in an application. Designing the user interface typically involves creating a class that derives from Form and then adding controls, setting properties, creating event handlers, and adding programming logic to the form.

  • Controls. Each component added to a form, such as a button, a text box, or a radio button is called a control. Typically, you set the properties to alter the appearance and behavior of controls.

  • Events. The Windows Forms programming model is event-based. When a control changes state, such as when the user clicks a button, it raises an event. To handle an event, an application registers an event-handling method for that event.

Web Applications

Web applications from a UNIX Web server are, usually, either a Common Gateway Interface (CGI) or Java Server Page (JSP). The CGI program is a standard for connecting external applications with information servers, such as Web servers.

A CGI program is executed in real time to generate dynamic information. For example, a CGI program on the Web server executes to transmit information to a database engine, retrieves result sets, and displays the result sets to the client browser.

JSP technology also enables development of dynamic Web pages. JSP technology uses tags and scriptlets written in the Java programming language to encapsulate the logic that generates the content for the page. The application logic resides in server-based resources such as a JavaBean component, which the page accesses by using the tags and scriptlets. Formatting tags such as HTML and XML tags pass directly back to the response page.

.NET provides ASP.NET, a unified Web development model that includes the services necessary for developers to build enterprise-class Web applications. ASP.NET provides Web Forms and Web services. Web Forms allow you to quickly build powerful forms-based Web pages. Web services enable the exchange of data using standards such as HTTP and XML messaging to move data across firewalls. XML Web services are not tied to a particular component technology or an object-calling convention. As a result, programs written in any language, using any component model, and running on any operating system can access XML Web services.

If an application uses CGI, then the migration strategy depends on the language in which the program was written. The languages include C/C++, Fortran, Perl, Tcl, UNIX shells, and Microsoft Visual Basic. Many Web developers write CGI programs in Visual Basic language because of its powerful text-handling capability. CGI2ASP is a framework for porting programs written in Visual Basic, using Windows CGI, to a component-based ASP application with virtually no change to the existing Visual Basic-based code.

If an application uses JSP technology, then you need to rewrite the JSP scriptlets (written in Java and residing in JavaBean components) in Microsoft Visual Basic Scripting Edition or Microsoft JScript and contained in ASP COM components. A tool named Java Language Conversion Assistant (JLCA) is also available for use in the Visual Studio .NET 2003 environment; this tool can automatically convert most JSP code to ASP.NET.

Database Applications

When moving the database applications to .NET, the most common migration strategy is to reengineer the application to use ADO.NET. Through ADO.NET, you can efficiently manage the database interactions in an application.

ADO.NET is an evolution of the Microsoft ActiveX® Data Object (ADO) data access model that directly addresses user requirements for developing scalable applications. ADO.NET was designed specifically for the Web, keeping scalability, statelessness, and XML in mind. The ADO.NET version that comes with Visual Studio .NET 2003 is version 1.1, which is the version used in this guide. A new version of ADO.NET 2.0 has been released with the latest release of Visual Studio .NET 2005. More details on various new features of ADO.NET 2.0 is available at https://msdn2.microsoft.com/en-US/library/ex6y04yf.aspx.

ADO.NET uses some of the ADO objects, such as the Connection and Command objects, and introduces some new objects, such as DataSet, DataReader, and DataAdapter.

The OLE DB and SQL Server .NET Data Providers (System.Data.OleDb and System.Data.SqlClient), which are part of the .NET Framework, provide five basic objects. These objects are the Connection, Command, DataReader, DataSet, and DataAdapter.

  • Connections. Used to connect to the database and manage the transactions against the database.

  • Commands. Used to execute the SQL statements against a database.

  • DataSets. Allow you to store the database schema and to program against flat data, XML data, and relational data.

  • DataReaders. Allow you to read a forward-only stream of data records from a data source.

  • DataAdapters. Used as a bridge between data source and data sets.

The records are mapped to the given commands accordingly. Figure 1.6 depicts the database interactions in ADO.NET.

Figure 1.6. Database interactions

Figure 1.6. Database interactions

Three of these objects have been developed since Connections and Commands were introduced. The following sections describe these new objects: DataSet, DataReader, and DataAdapter.

DataSet

The following are major features of the DataSet object:

  • DataSet is a stand-alone entity, which acts as a disconnected recordset that knows nothing about the source or destination of the data it contains. A DataSet contains entities such as tables, columns, relationships, constraints, and views.

  • DataSet is a memory-resident representation of data that provides a consistent relational programming model independent of the data source.

  • The DataSet has many XML characteristics, including the capability to produce and consume XML data and XML schemas. XML schemas can be used to describe schemas interchanged through Web services.

  • A DataSet with a schema can actually be compiled for type safety and statement completion.

  • The XML-based DataSet object provides a consistent programming model that works with all models of data storage including flat, relational, and hierarchical.

  • The DataSet is independent of the source of its data; the managed provider has detailed and specific information. The managed provider connects, fills, and persists the DataSets across the datastores.

DataReader

The following are major features of the DataReader object:

  • DataReader allows forward-only access over one or more of the resultsets obtained by executing a command and access to the column values within each row.

  • Results are stored in the network buffer on the client after the execution of a query until you request them.

  • DataReader increases application performance by retrieving data as soon as it is available instead of waiting for the entire results of the query to be returned.

  • DataReader allows storage of only one row at a time in memory to reduce system overhead.

DataAdapter

The following are major features of the DataAdapter object:

  • A DataAdapter is the object that connects to the database to fill the DataSet or DataReader and then connects back to the database to update the data, based on the operations performed while the DataSet held the data.

  • DataAdapter represents a set of data commands and a database connection that are used to fill the DataSet and update the data source.

  • DataAdapter serves as bridge between a DataSet and a data source for retrieving and saving data.

  • DataAdapter has command object properties like InsertCommand, UpdateCommand, and DeleteCommand to update the data.

References

More information on XML is available at https://msdn.microsoft.com/xml/.

More information on SOAP is available at

https://msdn.microsoft.com/library/en-us/dnsoap/html/understandsoap.asp .

More information on CLR is available at

https://msdn.microsoft.com/library/en-us/cpguide/html/cpconthecommonlanguageruntime.asp.

More information on Windows Forms is available at

https://msdn.microsoft.com/netframework/programming/winforms/.

More information on ADO.NET is available at

https://msdn.microsoft.com/library/en-us/cpguide/html/cpconoverviewofadonet.asp.

More information on wrapping unmanaged classes with Managed Extensions for C++ is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/vcmanexmigrationguidepart1_start.asp.

More information on interop marshaling is available at

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmex/html/vcgrfmanagedextensionsforcdatamarshalingtutorial.asp.

More information on .NET servers is available at

https://www.microsoft.com/windowsserversystem/default.mspx.

More information on .NET Framework security is available at https://msdn.microsoft.com/security/securecode/dotnet/default.aspx.

Download

Get the UNIX Custom Application Migration Guide

Update Notifications

Sign up to learn about updates and new releases

Feedback

Send us your comments or suggestions