Microsoft .NET Fundamentals for J2EE Developers


Microsoft .NET is a designation that reflects Microsoft’s realignment towards Internet operation and distributed applications. Microsoft .NET consists of three main components:

  • A language-independent application environment optimized for distributed operations — the .NET Framework.

  • A development environment for programming in several Microsoft languages — Visual Studio .NET.

  • The operating system that supports distributed environments and the .NET Framework — the Windows Server System.

The unifying vision behind the .NET initiative comprises the following:

  • Language-independent programming.

  • Enterprise-level scalability and reliability.

  • Integrated security.

  • Ease of implementation.

  • Distributed operation.

  • Support for open standards.

  • Robust operation and manageability.

  • Powerful debugging facilities.

Comparing .NET to J2EE

To seasoned Java developers, .NET may seem similar to the J2EE platform; both provide a structured way to create applications, both have languages that compile to intermediate code, and both provide a large library of APIs for application development. Indeed, many commentators from the Java world have noted that the conceptual jump from J2EE to .NET seems less than that from Windows DNA to .NET. However, .NET has at its core a different set of goals than the J2EE platform.

Java comprises the Java platform (runtime and APIs) and the Java language. The purpose of the Java platform is to support applications written in the Java language and compiled to Java bytecode. Although there have been attempts to compile other languages to Java bytecode, these have largely been academic exercises. The idea of Java has always been a single language on multiple operating systems.

.NET comprises the .NET Framework (runtime and APIs) and multiple supported programming languages. The purpose of the .NET Framework is to support applications written in any language and compiled to Microsoft Intermediate Language (MSIL). The goal of .NET is a single platform shared by multiple languages.

Investigating the .NET Framework

It is fundamental that you understand the .NET Framework and the services it provides for .NET-based applications.

Note

.NET-based applications or .NET Framework-based applications are applications that use the .NET Framework. This book uses .NET-based applications for brevity.

The .NET Framework includes class libraries that provide support for a wide range of tasks, including data access, security, file I/O, XML manipulation, messaging, class reflection, XML Web services, ASP.NET, and Microsoft Windows services.

Note

There are occasional comparisons between the .NET Framework and the Java 2 SDK, but the two are not directly equivalent.

A central part to this is the support for XML Web services. This technology is both a methodology and transport layer for passing information between components on different computers, different networks, and different operating systems.

Figure 2.1 shows the key features of the .NET Framework.

click to expand
Figure 2.1: .NET Framework components showing reliance on CLR

The .NET Framework is available as a freely redistributable component containing the tools, classes, and API support to run .NET-based applications. You must install the .NET Framework on any computer on which you want .NET-based applications to run.

Windows XP Service Pack 1 includes the .NET Framework version 1.0 and Windows Server 2003 comes with .NET Framework 1.1 as part of the operating system. For earlier versions of Windows, you can download the .NET Framework from the MSDN Web site. You can also install the .NET Framework from the Windows Update Service.

Note

The .NET Framework SDK includes the .NET Framework redistributable package.

There are multiple ways of installing the .NET Framework onto client computers. You can extract the .NET Framework redistributable package as an .msi file, so you (or your network administrator) can then distribute it using Active Directory Group Policy. Alternatively, larger enterprises can use Systems Management Server to deliver the package. Smaller organizations can opt for Software Update Services (SUS) to deploy the .NET Framework onto Windows 2000 clients. Developers can include the redistributable package in a build output from Visual Studio .NET, adding routines that detect for the presence of the framework on the client and installing or updating it if necessary.

Common Language Runtime

The common language runtime (CLR) is the core component of the .NET Framework. The CLR provides central functions for the hosting and operation of .NET-based applications. The main functions of the CLR are the following:

  • Just-in-time (JIT) compilation to native code.

  • Cross language integration.

  • Memory management and garbage collection.

  • Managed code operation.

  • JIT debugging.

  • Exception handling.

  • Security.

  • Runtime type safety checks.

  • Thread management.

    Note

    Although there are some differences, you can compare the CLR to the role of a Java Virtual Machine (JVM).

JIT Compilation to Native Code

When you deploy and run your application, the JIT complier carries out a quick check of the platform specification. For example, it will look at areas like processor type and numbers, memory, and so on. The JIT compiler then compiles the application to generate the machine code for that execution environment. This is the JIT compilation process.

Note

The JIT process in the .NET Framework is similar to the JVM runtime compiler.

Versions of Windows later than Windows NT 4.0 support only the x86 environment, which often leads people to wonder why they need to bother with the MSIL step and just compile directly for the x86 platform. However, not all x86-based computers are the same, and the MSIL route gives the maximum flexibility for future operating system developments.

JIT compilation takes into account the fact that an application may not call all the program code during execution. Rather than use processor time and memory to convert all the MSIL in a portable executable (PE) file to native code, it converts the MSIL as needed during execution and stores the resulting native code so that subsequent calls can access it. The loader creates and attaches a stub to each of a type’s methods when the type is loaded. On the initial call to the method, the stub passes control to the JIT compiler, which converts the MSIL for that method into native code and modifies the stub to direct execution to the location of the native code. Subsequent calls of the JIT-compiled method proceed directly to the native code that was previously generated, reducing the time it takes to JIT compile and run the code.

The effect of the JIT operation is that the first time an application executes, it takes marginally longer to start up. However, second and subsequent executions that call the JIT method are faster than a pre-compiled application, because the JIT component returns the previously generated native code, properly optimized for that computer.

The runtime supplies another mode of compilation called install-time code generation. The install-time code generation mode converts MSIL to native code just as the regular JIT compiler does, but it converts larger units of code at a time, storing the resulting native code for use when the assembly subsequently loads and runs. With install-time code generation, installing the application converts the entire assembly into native code, taking into account what is known about any currently installed assemblies. The resulting file loads and starts more quickly than it would have if it were being converted to native code by the standard JIT option.

Cross Language Integration

You might be surprised to learn that the CLR works with only one type of code. What, you may say, of the claim for language independence on the previous page? The answer is that the CLR works only with MSIL. The clever bit is that any programming language that supports .NET can create output in MSIL. This is where the language independence comes from. You can create .NET-based applications in one or more of the following languages:

  • Managed C++ (no surprises here)

  • C# (C Sharp — similarities to Java and C++)

  • Visual Basic .NET

  • J# (J Sharp — allows you write Java code for the .NET platform)

  • FORTRAN

  • Pascal

  • COBOL

  • PERL

  • Python

  • Eiffel

C# has proved a popular choice for both experienced Java developers and those new to the .NET platform, because it has many similarities to the Java programming language. J# provides a subset of the Java language that you can compile into MSIL and run on the CLR. However, regardless of the language you use, after you write your code, the compiler turns it into MSIL.

Note

If you are a glutton for punishment (or if you simply enjoy programming in machine code), you can write directly in MSIL. However, because MSIL is a pseudo-machine code, this is not an entirely intuitive process.

Memory Management and Garbage Collection

Memory management in the CLR centers on the process of garbage collection, which is similar to the equivalent process in Java. Garbage collection is a background operation that reviews objects committed to memory and recovers those that are no longer needed. Garbage collection acts on three generations, recovering short, medium, and long duration objects, known as Gen 0, Gen 1, and Gen 2 respectively.

All new objects start in the Gen 0 heap. The garbage collection algorithm works by checking to see if there are any objects in the heap that applications are not using.

Note

Many classes create temporary objects for their return values, temporary strings, and assorted other utility classes like enumerators and the like.

If there is not enough free memory in the heap to allocate to a new object, a garbage collection cycle commences on Gen 0 objects. If there is still not enough memory, a garbage collection cycle occurs on the Gen 1 objects, and then on Gen 2. A full pass garbage collection cycle is when the garbage collection processes all generations.

When a garbage collection cycle runs, it promotes all surviving objects to the next generation. Objects survive a garbage collection cycle because they are either still in use (reachable) or awaiting finalization. Surviving objects from Gen 0 go to Gen 1, and surviving objects from Gen 1 move to Gen 2. The garbage collection process then compacts and moves any freed memory to preserve contiguous space and to minimize memory fragmentation. Each generation garbage collection cycle typically occurs on a 1:10 ratio compared to the generation below it, for example, 10 Gen 0 collections occur to every Gen 1, and 10 Gen 1 to every Gen 2.

Note

Higher level garbage collections are more expensive in terms of system resources — the garbage collectors expect a bigger tip.

Managed Code Operation

The forth major function of the .NET Framework is managed code operation. The definition of managed code is fairly simple — managed code uses the CLR, unmanaged code does not. To tighten up on this definition, managed code executes completely within the CLR. Calls to unmanaged components (serviced components, COM, or DCOM objects) come outside the remit of the CLR. Hence CLR garbage collection and other functions do not operate against unmanaged code or unmanaged code components.

Just-In-Time Debugging

Just-in-time (JIT) debugging is a technique for debugging a program that you start outside Visual Studio. If you have enabled JIT debugging, the program brings up a dialog box when a crash occurs. This dialog box asks if you want to debug the program and which debugger you want to use.

JIT debugging gives you the flexibility of choosing a debugger when an exception occurs. It also lets you debug on clones of your production computers, which helps identify programming issues more quickly.

Exception Handling

The CLR handles exceptions in .NET Framework applications, but it also provides functions for exception management. The main ones of these are the Try/Catch/__Finally blocks you can use to catch both managed and unmanaged exceptions. The basic approach is to use a Try clause when you are about to carry out a risky operation paired with a Catch clause if the function in the Try statement causes an exception. The __Finally clause should run whether the exception occurred or not.

Security

The CLR enforces security with executing applications either through the use of XML formatted configuration files or through the Runtime Security Policy node of the .NET Framework 1.1 Configuration Tool (Mscorcfg.msc). Security configuration files contain information about the code group hierarchy and permission sets associated with a policy level.

The .NET Framework Configuration tool shows the three main security configuration levels of Enterprise, Machine, or User. These levels correspond to the three security configuration files (Enterprisesec.config, and two separate Security.config files for the computer and user levels).

The .NET Framework Configuration tool lets you manage permission sets (for example, FullTrust, LocalIntranet, Everything, and so on) and code groups, such as My_Computer_Zone, LocalIntranet_Zone, Trusted_Zone, and so on. Each code group has a related permission set, for example, the Trusted_Zone maps to the Internet permission set.

Assemblies that meet the code group’s membership condition receive the associated permissions from the permission set. A permission set might include whether the application can access the File Open dialog box, whether it can print, or what sort of user interface it can display.

Although you can edit the security configuration files directly, it is strongly recommended that you use the .NET Framework Configuration tool or Code Access Security Policy tool (Caspol.exe) to modify security policy. This ensures that policy changes do not corrupt the security configuration files.

Runtime Type Safety Checks

The .NET Framework also enforces security through runtime type safety checks. With type safe code, the common language runtime can completely isolate assemblies from each other. This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability. Type-safe components can execute safely in the same process even if they are trusted at different levels.

Type-safe code accesses only the memory locations it is authorized to access. For example, type-safe code cannot read values from another object’s private fields. It accesses types only in well-defined, allowable ways.

Although verification of type safety is not mandatory to run managed code, type safety plays a crucial role in assembly isolation and security enforcement. When code is not type safe, unwanted side effects can occur. For example, the runtime cannot prevent unsafe code from calling into native (unmanaged) code and performing malicious operations. When code is type safe, the runtime’s security enforcement mechanism ensures that it does not access native code unless it has permission to do so.

During JIT compilation, an optional verification process examines the metadata and MSIL of a method to be JIT-compiled into native machine code to verify that they are type safe.

Thread Management

The common language runtime provides support for multithreaded applications, mainly through the ThreadPool class. ThreadPool provides automatic thread creation and management mechanism for most tasks.

Common Type System

The common type system (CTS) defines how applications and the .NET Framework can declare, use, and manage types within the runtime, and is also an important part of the runtime’s support for cross-language integration. It is the CTS that allows large teams of developers to work on an application, each programming in any of the many languages that the .NET Framework supports.

The CTS performs the following functions:

  • Establishes a framework that enables cross-language integration, type safety, and high performance code execution.

  • Provides an object-oriented model that supports the complete implementation of many programming languages.

  • Defines rules that languages must follow, which helps ensure that objects written in different languages can interact with each other.

Managed code operation implements type safety through CTS, so the CTS ensures that all .NET-based application components are self-describing. The .NET Framework then handles the references between managed code components.

The Global Assembly Cache

Installing the .NET Framework creates a machine-wide code cache called the global assembly cache. The global assembly cache stores assemblies (executable or library files) specifically designated for sharing by several applications on the computer. In conjunction with the Strong Name Tool, it also enables you to run two or more versions of an assembly with the same name. This gives greater control over assembly selection at runtime than with the CLASSPATH statement.

There are two versions of the global assembly cache — MSCORWKS is the workstation version that runs on Windows XP and any desktop operating system on which you can install the .NET Framework. MSCORSVR is an integral part of the Windows 2003 Server family and installs as a component of the .NET Framework on Microsoft’s other server operating systems. MSCORWKS functions best with single user .NET-based applications whereas MSCORSVR works in large, multiprocessor, multi-user environments.

Normally, you place an application’s assemblies in the application installation directory. However, you may want more than one application to use the same assembly, so rather than copy it into two separate directories, you can place the assembly into the global assembly cache.

Note

You must sign assemblies with the Strong Name Tool before placing them in the global assembly cache.

There are several ways to deploy an assembly into the global assembly cache:

  • Use an installer designed to work with the global assembly cache. This is the preferred method.

  • Use a developer tool called the Global Assembly Cache tool (Gacutil.exe), part of the .NET Framework SDK.

  • Use Windows Explorer to drag the assemblies into the cache.

For more information about best practices for deploying assemblies into the global assembly cache, see Deploying .NET Framework-based Applications, on MSDN.

Strong Names

The .NET Framework enhances security by letting you digitally sign each code component with the Strong Name Tool (SN.exe). Strong-named assemblies consists of the assembly’s identity — its simple text name, version number, and culture information (if provided) — together with a public key and a digital signature.

By creating strong-named assemblies you can support multiple DLLs with the same name in the global assembly cache. Applications then only use the DLL version that they installed, addressing the common issue of DLL conflicts. The use of strong-named assemblies makes it possible for you to install new versions of an assembly side-by-side with an older version of the assembly without conflicts occurring.

Note

To avoid dependencies on assemblies that do not have strong names, strong-named assemblies can only reference other strong-named assemblies.

.NET Remoting

.NET Remoting is Microsoft’s new communication mechanism for distributed applications built on the .NET Framework. NET Remoting is similar in function to Remote Method Invocation (RMI) in J2EE.

.NET Remoting enables you to build widely distributed applications easily, whether application components are all on one computer or spread out across the entire world. With .NET Remoting, you can build client applications that use objects in other processes on the same computer or on any other computer that is reachable over its network. You can also use .NET Remoting to communicate with other application domains in the same process.

.NET Remoting provides an abstract approach to interprocess communication that separates the remotable object from a specific client or server application domain and from a specific mechanism of communication. As a result, it is flexible and easily customizable. You can replace one communication protocol with another or one serialization format with another without recompiling the client or the server. In addition, the remoting system assumes no particular application model. You can communicate from a Web application, a console application, a Windows Service — from almost anything you want to use. Remoting servers can also be any type of application domain. Any application can host remoting objects and provide its services to any client on its computer or network.

To use .NET Remoting to build an application in which two components communicate directly across an application domain boundary, you need to build only the following:

  • A remotable object.

  • A host application domain to listen for requests for that object.

  • A client application domain that makes requests for that object.

You can think of .NET Remoting in this way even in a complex, multiclient/multiserver application. You must also configure the host and the client application to link into the remoting infrastructure and you must understand the lifetime and activation issues that the remoting infrastructure introduces.

Building a .NET-based Application

There are several ways in which you can write and build .NET-based applications. The main ones are the following:

  • Use Visual Studio .NET to write and build the application.

  • Use your favorite development environment and the command-line compiler.

  • Use a text editor and the command-line compiler.

Using Visual Studio .NET 2003

Visual Studio .NET 2003 is the latest release of Microsoft’s application development environment, which installs along with the MSDN Library for Visual Studio .NET. Visual Studio .NET is fully in tune with the language neutral approach, making it very easy to create interoperating projects in different languages. It provides built-in templates for different projects, depending on the language you want to use. Project types include the following:

  • Windows Forms-based applications.

  • ASP.NET Web applications.

  • ASP.NET Web services.

  • Class libraries.

  • Console applications.

  • Windows services.

Additionally, Visual Studio lets you package applications for distribution, creating Windows Installer packages, CAB files, and setup routines.

Using Command Line Compilers

You may be pleased to know that there is no requirement to use Visual Studio .NET to create .NET-based applications. The alternative is to use the command line compilers in the .NET Framework SDK in a similar fashion to how you would use JAVAC and the J2SE SDK.

You can download the English version of the .NET Framework SDK v1.1 from the SDK Web site.

When you install the .NET Framework SDK, this creates the %WINDIR%\Microsoft.NET\Framework\versionnumber directory, where versionnumber is v1.0.3705 for .NET Framework version 1.0 and v1.1.4322 for version 1.1. Within that directory, you find the following command line compilers:

  • CSC.EXE for C# applications.

  • VBC.EXE for Visual Basic.

  • JSC.EXE for J#.

Running the compiler with the correct command line switches produces one or more assemblies that the CLR can then execute. Assemblies are usually .exe or .dll files.

Note

To examine the contents of an .exe or .dll file, use the Ildasm.exe disassembler tool included with the .NET Framework (SDK).

.NET assemblies include descriptive metadata, such as the Windows Portable Executable Header, assembly dependencies, and version information. However, there is no direct comparison to an assembly in Java. The closest comparison is to a JAR file, which contains classes storing metadata and can cross reference information to other JAR files without requiring a CLASSPATH value.

Locating Assemblies with the Global Assembly Cache

The .NET Framework does not use a variable like CLASSPATH, but instead uses the global assembly cache mentioned earlier. The global assembly cache exists on each computer and is both a folder and a database of registered components. The folder is under %WINDIR%\ASSEMBLY, and you register an assembly with Gacutil.exe.

Note

When you create installation packages in Visual Studio .NET, you include the registration process as part of the installation.

To view the global assembly cache, complete the following steps.

To inspect the global assembly cache

  1. Click Start, point to All Programs, point to Administrative Tools, and then click Microsoft .NET Framework 1.1 Configuration (or 1.0). The .NET Configuration 1.1 (or 1.0) management console appears.

  2. Double-click the Assembly Cache node in the left pane.

  3. In the right pane, click the View List of Assemblies in the Assembly Cache link. A list of registered assemblies appears.

  4. Right-click an assembly, and then click Properties. The Assemblyname Properties dialog box appears.

The Version value allows multiple versions to coexist and to let a component such as an executable call a specific DLL. Version numbers are of the form:

MajorVersion.MinorVersion.BuildNumber.Revision

For example, 7.0.5000.0 is a common version number for the Microsoft.VSDesigner assembly.

The Public key token is a result of the code signing process that uniquely identifies each assembly. This ensures that an application only loads the correct assembly, preventing malicious or unintentional substitution of an application component.

Understanding Attributes

Attributes are a feature of most Microsoft software components, such as Interface Definition Language (IDL) interfaces in COM, so it should not be a surprise that these appear in the .NET Framework. Current versions of the Java 2 SDK do not include support for attributes, although the proposed Java 2 SDK 1.5 declares support for attribute-like structures. For more details see:

  • JSR 175: A Metadata Facility for the Java Programming Language

  • New Language Features for Ease of Development in the Java 2 Platform, Standard Edition 1.5: A Conversation with Joshua Bloch

An attribute in the .NET Framework has both keyword and tag-like elements to it. You use tags to document types, fields, document classes, and methods at design time. The assembly metadata contains the attribute information. Many of the standard namespaces in the .NET Framework contain attributes, and developers can implement their own custom attributes if necessary.

An example of an attribute is WebMethod. This attribute indicates that you can call a method within a class as an XML Web service. If you place the WebMethod tag at the start of the method, the compiler then generates additional information that exposes the method as an XML Web service.

The following lines of code show the simplest demonstration of this.

 [WebMethod] public String HelloWorld() {     … } 

Attributes can accept parameters as part of the tag. This is similar to a constructor class.

 [WebMethod(Namespace="http://www.microsoft.com/Interoperability")] 

This assigns the namespace property of the WebMethod attribute to the specified URL.

Note

The CLR supports attributes in any language, although the development language syntax controls how you prefix a tag.

Creating Web Applications

In Java, you create Web applications using JSP pages and servlets. In .NET, you use the latest evolution of Active Server Pages (ASP) named ASP.NET. Normally, ASP.NET applications would run on Internet Information Services (IIS), but this is not a strict requirement. For example, you can also run ASP.NET applications on platforms such as Apache 2.0-based Enterprise Ready Server.

ASP.NET provides enhanced functionality over JSP, with features such as code-behind and event driven Web controls. To implement equivalent functionality in JSP, you need both the scripting language and a set of additional tools. The experience of developers familiar with both Java and .NET is that ASP.NET is more powerful than JSP, which is itself better than the earlier ASP. The introduction of JavaServer Faces is expected to level the playing field between ASP.NET and JSP.

ASP.NET applications tend to have graphical front ends, so developers tend to prefer using Visual Studio .NET to create and edit ASP.NET pages. An alternative free integrated development environment (IDE) is Web Matrix, available for download from the ASP.NET Web site.

You can create ASP.NET Web applications in any language that the .NET Framework CLR supports. This gives you the flexibility to work in any programming language, or even create a Web site by combining elements built in different languages by a team of developers.

Hosting Components

The .NET Framework does not have a direct equivalent to EJBs. However, there are three main techniques you can use to provide hosted components for enterprise applications:

  • Run as a Windows service.

  • Host on IIS.

  • Use component services.

Running as a Windows Service

Windows services (or NT services) are system level processes that run on a computer regardless of the logged in user. Typical services include functions of the operating system, schedulers, virus scanners, database engines, and network components.

You can use templates from within Visual Studio .NET to take a .NET assembly and run it as a service. This generates an application that runs as long as the computer is running.

Note

Applications running as a service need to deal with their own networking arrangements. In particular, they should run under a domain account, not the local machine account. This is because the local machine account only has rights on the local computer.

Hosting through IIS

Internet Information Services provides a framework for hosting Presentation and Business tier components. Using a configuration file associated with the assembly, you can configure support within IIS for the following:

  • Deploying assemblies.

  • Handling incoming connections.

  • Supporting protocols.

  • Implementing connection pooling.

  • Configuring security.

The alternative approach would be to build your own custom framework to host assemblies. However, this would be a time-consuming and cumbersome task.

Using Component Services

Hosting an assembly in IIS is easy and convenient, but it does not provide the full functionality that EJBs enjoy. Component services (or COM+) provide the additional features, such as:

  • Recycling

  • State management

  • Transaction support

  • Method-level security

  • Logging

  • Impersonation

  • Message queue support

A .NET developer can address COM+ properties either through the component services administration tool or using programmatic attributes.

Note

There is no equivalent of container managed persistence (CMP), container managed relationships or EJB-QL in .NET, although there are a number of third party implementations. Visual Studio .NET has tools for auto-generating SQL statements and dragging and dropping database tables into the IDE.

Supporting Web Services

One area where Microsoft has invested considerable effort is in supporting Web services. ASP.NET Web services are the preferred technology for implementing Web services based on the .NET Framework.

ASP.NET Web services support service requests using SOAP over HTTP. ASP.NET Web services automatically generate WSDL and discovery (.disco) files for Web services. You can use ASP.NET Web services to implement a Web service listener that accesses a business fa ade implemented as a COM component or managed class. The .NET Framework SDK also provides tools to generate proxy classes that client applications can use to access Web services.

Connecting to Databases

The .NET Framework provides ADO.NET (formerly ActiveX Data Objects) as a framework for connecting to databases. From an architect’s perspective, ADO.NET represents the abstract design concepts that you can use to build the data access classes within the .NET Framework. From a developer’s perspective, ADO.NET represents the concrete implementation of classes inside the .NET Framework that the Framework then uses for data access.

Note

ADO.NET provides functions similar to those implemented in JDBC and JDO.

There are several main design goals to ADO.NET:

  • Explicit and factored object model — ADO.NET is a simple-to-use object model in which the developer has complete control over how to control data source connectivity, command execution, and data manipulation.

  • Disconnected data cache model — N-tier programming and XML Web service architecture require that applications can participate in a disconnected, loosely coupled manner. ADO.NET provides a comprehensive caching data model for marshalling data between applications or services and then updating the original data sources or source optimistically.

  • XML support — XML is the key to building interoperable applications and more robust data processing models. XML support is directly included into the .NET Framework and ADO.NET uses this implementation by providing a seamless interaction with XML in either a relational manner or in a native XML manner.

You can divide the ADO.NET architecture into two logical pieces: command execution and caching. Command execution requires features like connectivity, execution, and reading of results and the .NET data providers enable these features. The DataSet function handles caching of results.

Implementing Collections

A collection is a set of similarly typed objects that you can group together. These are the equivalent of java.util.collections on the J2EE platform.

You can group objects of any type into a single collection of the type Object to take advantage of constructs inherent in the programming language. For example, the C# foreach statement expects all objects in the collection to be of a single type.

However, in a collection of type Object, additional processing, such as boxing and unboxing or conversions, affects the performance of the collection. Boxing and unboxing typically occur when storing or retrieving a value type in a collection of type Object.

Strongly typed collections, such as StringCollection, avoid these performance hits, if the type of the element is the type that the collection is intended for (for example, storing or retrieving strings from a StringCollection). In addition, strongly typed collections automatically perform type validation of each element added to the collection.

You can categorize collections classes into three types:

  • Generic collections — The common variations of data collections, such as hash tables, queues, stacks, dictionaries, and lists.

  • Bit collections — Collections whose elements are bit flags. They behave slightly differently from other collections.

  • Specialized collections — Collections with highly specific purposes, usually to handle a specific type of element, like the StringDictionary.

Accessing Directory Services

Accessing directory services under .NET usually means connecting to Active Directory, either using Lightweight Directory Access Protocol (LDAP) or Active Directory Service Interface (ADSI), the equivalent of JNDI.

Microsoft implements the LDAP API in Wldap32.dll — also referred to as “LDAP C” or “C binding LDAP.” Applications written in LDAP are compatible only with LDAP directory services, although Active Directory also fully supports the LDAP APIs for directory access.

The primary and recommended API for Active Directory is ADSI. ADSI sits on top of LDAP and also provides the easiest access to Active Directory through LDAP. Native ADSI allows access to Active Directory by exposing objects stored in the directory as COM objects. You then manipulate directory objects using the methods on one or more COM interfaces.

ADSI providers contain the implementation of ADSI objects for a particular namespace, with the main one being the ADSI LDAP provider. By implementing the required interfaces, ADSI providers translate these interfaces to the API calls of a particular directory service.

The ADSI LDAP provider operates on the ADSI client to provide access to Active Directory or to other LDAP directory services. The ADSI LDAP provider works with any LDAP server that supports LDAPv2 or later.

For more information about the LDAP API and about programming in LDAP, see the Microsoft Platform SDK link on the Web Resources page.

Reflection

Reflection allows you to write code that can dynamically examine a data type or an object at run time. You can get a list of its methods, its interfaces, and even its class-level variables. Reflection even allows you to interact with an object by calling those dynamically discovered methods or putting values in those dynamically discovered variables.

Using Reflection, you can create object browsers, applications that list and document methods, or even highly configurable metadata driven applications that create objects and invoke methods based on instructions from a table or XML file. These are powerful capabilities that you can use in .NET-based applications.

You should be aware that Reflection also gives you the power to perform potentially dangerous operations. You can use Reflection to call methods that are Private in scope. You can also put values directly into an object’s variables without calling any business logic. Reflection provides you with the tools to misuse objects in very dangerous ways. However, you can use these capabilities to create very powerful code, such as code to load data from a DataSet into an object based on metadata that matches the object’s variable name to a column name in a table.




Application Interoperability. Microsoft. NET and J2EE
Application Interoperability: Microsoft .NET and J2EE: Microsoft(r) .Net and J2ee (Patterns & Practices)
ISBN: 073561847X
EAN: 2147483647
Year: 2003
Pages: 104

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