To better understand developing applications using ADO.NET, this chapter from ADO.NET: The Complete Reference by Michael Otey and Denielle Otey (McGraw-Hill/Osborne, 2003, ISBN: 0-07-222898-9) introduces the .NET architecture. Because few applications are stand-alone database applications that just need to access database resources and nothing else, you'll also need to know which of the .NET Namespaces to include in your applications to enable access to other system resources.
Before launching into building ADO.NET applications, it's good to have a solid understanding of the new Microsoft .NET Framework. The .NET Framework is Microsoft's new development platform that brings with it enormous changes in the nature of the applications that are developed, as well as the development tools and methodologies that are used to develop those applications. To help you get a more complete understanding of the applications that you develop using ADO.NET and the Microsoft .NET Framework, this chapter starts out with an introduction to the new Microsoft .NET architecture, where you'll learn about the Common Language Runtime (CLR) and the Common Type System (CTS). The next part of this chapter provides a general overview of the major Namespaces in the .NET Framework. Very few applications are stand-alone database applications that just need to access database resources and nothing else. In order to access other system resources, you need to understand which of the .NET Namespaces you need to include in your applications. Next, you'll get a more in-depth look at the anatomy of programs (aka assemblies) that are created when you build .NET applications. Understanding the context of the .NET assemblies can help you understand the deployment issues that are encountered when deploying .NET applications.
The .NET System Requirements
The first thing you need to know about .NET applications is where they can run. In this section, you can see the hardware and software requirements for .NET Client and .NET Server applications.
Hardware Requirements
Table 2-1 lists the .NET hardware requirements. These hardware requirements are divided into requirements for client/desktop applications, as well as server-side ASP.NET applications. This table lists the Microsoft minimum and recommended system specifications. In typical Microsoft fashion, they've low-balled their hardware recommendations. Although .NET applications may run in these low-powered systems specified in the minimum columns, in my experience, you'll be a lot happier with a faster system. We've included a "Better" column indicating a more desirable system specification. But bear in mind that, like most computer systems, "more is better" and you'll definitely get a better .NET experience running .NET applications on faster hardware.
Platform
CPU
CPU
CPU
RAM
RAM
RAM
Minimum(MHz)
Recommended(MHz)
Better(MHz)
Minimum(MB)
Recommended(MB)
Better(MB)
.NET Client
90
90+
350+
32
96+
128+
.NET Server
133
133+
450+
128
256+
512+
Table 2-1..NET Hardware Requirements
Operating System Requirements
In addition to the hardware requirements, .NET applications also have a minimum required operating system level to support the various .NET features. Table 2-2 shows the .NET Framework software requirements.
Platform
Operating System
Additional Software
.NET Client
Windows 98
Windows 98 SE
Windows ME
Windows NT 4.0 Workstation
Service Pack 6a
Windows NT 4.0 Server
Service Pack 6a
Windows 2000 Professional
Windows 2000 Server
Windows 2000 Advanced Server
Windows 2000 Datacenter Server
Windows XP Home Edition
Windows XP Professional
.NET Server
Windows 2000 Professional
Service Pack 2
Windows 2000 Server
Service Pack 2
Windows 2000 Advanced Server
Service Pack 2
Windows 2000 Datacenter Server
Service Pack 2
Windows XP Professional
Windows 2003 Server Family
Table 2-2..NET Operating System Requirements
Database Access Requirements
In addition to the previously mentioned hardware and software prerequisites, certain database access features used by the .NET Framework have minimum MDAC (Microsoft Data Access Components) levels that are required (see Table 2-3). MDAC is included in the installation process for the .NET Framework and Visual Studio.NET, so you don't need to worry about it in a development environment. However, you do need to be concerned about this when you deploy your client and server applications. You can download the Microsoft MDAC support from http://www.microsoft.com/data.
Platform
Middleware
Notes
.NETClient
MDAC 2.6
Needed by the SQL Server .NET Data Provider
.NETServer
MDAC 2.7
Needed by the SQL Server .NET Data Provider
Table 2-3.NET Database Access Requirements
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
The three primary components of the .NET architecture are the Common Language Runtime (CLR), the Common Type System (CTS), and the .NET Framework class libraries. The CLR is essentially the runtime engine that executes .NET applications; the CTS defines all of the basic data types as well as the operations that can be performed on those data types. The .NET Framework class libraries is a base set of classes grouped into Namespaces that provide access to system resources as well as standard language capabilities, such as string manipulation, I/O, and numerical functions. Figure 2-1 presents the overall architecture of the .NET Framework.
Figure 2-1.An overview of the .NET Framework architecture
In the following sections, you'll get a more detailed look into each of these core components that comprise the .NET architecture.
The Common Language Runtime
The job of the CLR is basically to load and run .NET applications. The CLR marks a big change from Microsoft's earlier methods of software development where your application glues together many separate components in order to perform various functions. In many ways, the CLR is analogous to Java's JVM (Java Virtual Machine) or to VB 6's MSVBSM.DLL in that it's a runtime layer over the operating system. However, the CLR goes beyond the capabilities of either of these by enabling cross-language integration, self-describing components, xcopy deployment, and integrated security. The CLR's most essential task is to compile .NET code into native machine instructions and execute those instructions. The code that runs in the CLR is called managed code; any code that runs outside of the CLR is referred to as unmanaged code. Managed code basically describes the situation where the CLR-not the programmer-is responsible for performing tasks such as memory allocation and exception handling.
The CLR enables a couple of key improvements over previous Microsoft development scenarios. First, the CLR enables cross-language object inheritance and exception handling, and, in addition, it provides resource management for program objects. Code that's developed using any language that targets the .NET runtime can be used to create objects that can be inherited by other languages. For example, objects that are created using C#, J#, or Managed VC++ can be seamlessly integrated into Visual Basic.NET applications. Likewise, any exceptions raised in those objects will appear exactly like native Visual Basic.NET exceptions because they all conform to the .NET error handling standards. The CLR also automatically handles memory management tasks. The CLR is responsible for allocating the memory required by an object. Further, its automatic garbage collection takes care of releasing those resources when they're no longer used-freeing the programmer from that responsibility. Cross-language integration results in more easily reusable code, and automatic resource management results in more robust programs.
When .NET programs are created, the compiler doesn't produce code that can be natively executed. Instead, the .NET compiler outputs assemblies that contain a combination of Microsoft Intermediate Language (MSIL) and metadata information. See the "Assemblies" section, later in this chapter, for more detailed information.
NOTE: The .NET Framework SDK provides both an MSIL compiler (ILasm.exe), as well as an MSIL decompiler (ILDasm.exe).
In Figure 2-2, you can see an overview of the basic process that the CLR uses for execution and assembly.
Figure 2-2.Program execution in the CLR
As Figure 2-2 illustrates, .NET source code is compiled into an assembly either using one of the command-line compilers provided by the .NET Framework SDK or by Visual Studio.NET. Much like standard unmanaged code, the files containing these assemblies typically end in the extension .exe or .dll. When the CLR executes an assembly, the class loader first parses the metadata contained in the assembly to pull out the MSIL code as well as discover any dependencies that the assembly has. Next, the CLR's Just-In-Time (JIT) compiler will compile the MSIL code into native code that can be executed on the system. However, don't think that the entire program is compiled all at once. Instead, the JIT compiles each function as it is called. Once the JIT has compiled a function, it stores the address of the compiled code, which will be directly executed for all future function calls. In addition, the .NET Framework also includes an install-time compile option that will convert the entire assembly to native code as part of the installation process.
As you might expect, there's no such thing as a free lunch, and the CLR is no exception to this axiom. Although the CLR enables a number of powerful new language capabilities, it does come at a price. The CLR is required to run .NET applications, and it doesn't come preinstalled with Windows XP or Windows 2000 Professional, or any Windows platform other than Windows 2003 Server. Instead, either the CLR must be deployed along with your .NET applications or it must be deployed prior to deploying your .NET applications. Moreover, the CLR's footprint weighs in at a hefty 20MB, making it a significant consideration, especially for client installations.
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
The CTS implements the formal specifications for the type system used by the .NET Framework. All data types represented by the CTS are objects. The CTS defines how a type is defined and the operators that it can accept. One of the primary goals of the CTS is to enable deep language integration by allowing code that's written in one language to be inherited and used by another language. Sharing a common system of data types is one of the most fundamental building blocks that enable this to happen.
Classes of Types
The .NET Framework supports two basic classes of types: value types and reference types. The following section describes these types in more detail.
Value Types - Value types are very similar to the built-in data types provided by most programming languages. Typical data types that are used to store variable values include characters, integers, strings, and floating-point numbers. In the .NET Framework, they are termed value types because they are copied when they are passed as arguments. In other words, they are passed by value. The .NET Framework stores value types on the stack. Table 2-4 lists the value type supported by the .NET Framework along with their VB.NET and C# data type keywords.
Type
Description
VB.NET
C#
Boolean
A Boolean value (true or false)
Boolean
bool
Byte
An 8-bit unsigned integer
Byte
byte
Char
A Unicode (16-bit) character
Char
char
Decimal
A 96-bit decimal value
Decimal
decimal
Double
A double-precision (64-bit) floating-point number
Double
double
Int16
A 16-bit signed integer
Short
short
Int32
A 32-bit signed integer
Integer
int
Int64
A 64-bit signed integer
Long
long
IntPtr
A signed integer whose size depends on the underlying platform
IntPtr
IntPtr
Object
The root of the object hierarchy
Object
object
SByte
An 8-bit signed integer
SByte
sbyte
Single
A single-precision (32-bit) floating-point number
Single
float
String
An immutable, fixed-length string of Unicode characters
String
string
UInt16
A 16-bit unsigned integer
UInt16
ushort
UInt32
A 32-bit unsigned integer
UInt32
uint
UInt64
A 64-bit unsigned integer
UInt64
ulong
UIntPtr
An unsigned integer whose size depends on the underlying platform
UIntPtr
UIntPtr
Table 2-4.CTS Value Types
Reference Types - Reference types store a reference to the value's memory address, and are allocated on the heap. Reference types can be self-describing types, pointer types, or interface types. Unlike value types, reference types are passed between procedures using the address. In other words, a reference to the original object is passed rather than a copy of that object, as is the case with value types.
Type
Description
VB.NET
C#
Classes
A class is a data structure that may contain data members (constants, variables, and events), function members (methods, properties, indexers, operators, and constructors), and nested types.
Class
class
Delegates
A delegate is a reference type that refers to a shared method of a type or to an instance method of an object.
Delegate
delegate
Arrays
An array is a data structure that contains a number of variables (elements of the array).
Dim MyArray(5) As Integer
int[] myArray=
Interfaces
Interfaces are implemented by other types to guarantee that they support certain operations. An interface defines a contract. A class or structure that implements an interface must adhere to that contract.
Interface
interface
Pointers
Pointers reference blocks of memory. There are three kinds of pointers supported by the runtime: managed pointers, unmanaged pointers, and unmanaged function pointers.
N/A
int*
Table 2-5.CTS Reference Types
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
The .NET Framework class library contains a collection of programming classes that enable your applications to perform various functions. These classes are organized into related groupings referred to as Namespaces. As the name implies, all class names with a given Namespace must be unique. The .NET Framework Namespaces use a dot notation syntax scheme to describe a hierarchical organization. This naming scheme allows developers to easily group together related classes as well as to extend the functionality of a Namespace in an organized and easy-to-understand manner. Namespaces adhere to the following naming pattern: companyname.technologyname. One clear example of this is the Microsoft.Win32 Namespace, which is a Microsoft-created Namespace that contains classes that enable an application to access the Win32 API set. Another example of this naming scheme within the .NET Framework is the System.Data Namespace, which is the root level of the ADO.NET classes. Two examples of the classes that are grouped together at the next level of the System.Data class hierarchy are the System.Data.SqlClient and the System.Data.OledbClient. Each of these sets of classes are independent. No functions in the System.Data.SlqClient require the System.Data.OleDbClient, and vice versa. Further, each of these sets of classes are dependent on and subordinate to the System.Data level.
Using the different .NET Namespaces and classes in your applications is really quite easy. To use the classes contained in a given Namespace in your application, you just need to include an import directive for that Namespace. The most difficult part of using the .NET Framework class libraries is knowing which Namespace provides support for what type of functionality. By default, all .NET applications include the System Namespace, which provides basic support for variables and data types like Objects, Bytes, Int32, and Strings, as well as the Exception classes that provide structured error handling. However, to provide support for other functions, you need to include various Namespaces from the .NET Framework class libraries. Using the ADO.NET System.Data Namespace to provide database access is one of the best examples of this. In order to use ADO.NET and access databases from your .NET application, you need to include the System.Data Namespace, which enables your application to use the data access classes and methods provided by the ADO.NET technology. More detailed information about ADO.NET is presented in the next chapter of this book. Familiarizing yourself with the basic Namespaces in the .NET Framework is a vital step toward using the .NET Framework effectively and productively. The following section provides an overview of the class libraries provided with the Microsoft .NET Framework.
Microsoft Namespaces
Table 2-6 provides a brief overview of the different Microsoft Namespaces provided as a part of the .NET Framework.
Namespace
Description
Microsoft.CSharp
Contains the classes required to compile C# source code
Microsoft.JScript
Contains the classes required to support the JScript runtime
Microsoft.VisualBasic
Contains the classes required to compile Visual Basic.NET source code as well as the Visual Basic runtime
Microsoft.Vsa
Provides classes that enable you to integrate the .NET scripting interface in your applications
Microsoft.Win32
Contains the classes that enable your application to handle events that are raised by the system as well as classes that enable your application to read and write to the Registry
Table 2-6. Microsoft Namespaces in the .NET Framework Class Library
System Namespaces
Table 2-7 provides a brief overview of the different Namespaces provided by the System Namespace in the .NET Framework class library.
Namespace
Description
System
The most fundamental of all the .NET Framework Namespaces; it must be used by all applications, and it contains the classes that represent the basic data types that were presented earlier in the "Common Type System" section.
System.CodeDom
Contains classes that are used to represent a source code document.
System.Collections
Contains classes used to manage collections of objects.
System.ComponentModel
Provides classes that control the design-time and runtime behavior of components and controls.
System.Configuration
Contains classes that enable your application to access the .NET Framework configuration settings.
System.Data
Provides support for ADO.NET and its database access classes and data types. The basic ADO.NET data management classes contained in the System.Data Namespace are the DataSet and DataTable classes that enable disconnected data access for Windows and Web-based applications. The specific System.Data classes are discussed in more detail in the next chapter.
System.Diagnostics
Contains classes that enable your application to manage system processes as well as read the system event logs and performance monitor counters.
System.DirectoryServices
Contains classes that enable your application to access the Active Directory via the ADSI(Active Directory Services Interface).
System.Drawing
Contains classes that access the system's GDI+ functions, which provide graphics support.
System.EnterpriseServices
Contains classes that provide access to COM+ for
n-tiered enterprise application support.
System.Globalization
Contains classes that enable National language Support (NLS) as well as support for Calendar objects.
System.IO
Contains classes that enable your applications to read and write to data streams either synchronously or asynchronously.
System.Management
Contains classes that provide access to the WMI (Windows Management Interface) infrastructure to provide systems monitoring and management support.
System.Messaging
Contains classes that enable your application to read and write messages for the Microsoft Messaging Queuing technology.
System.Net
Contains classes that enable your application to conduct network communications using HTTP, as well as TCP and UDP sockets.
System.Reflection
Contains classes that enable the application to read the metadata of a loaded assembly.
System.Resources
Contains classes that enable your application to store and load regional-specific resources.
System.Runtime.ComplierServices
Contains classes that allow compiler developers to control aspects of the runtime behavior of the CLR.
System.Runtime.InteropServices
Contains classes that enable your .NET applications to interface with COM (Component Object Model) objects and native Win32 APIs (Application Program Interfaces).
System.Runtime.Remoting
Contains classes that enable your application to manage remote objects required for developing distributed applications.
System.Runtime.Serialization
Contains classes that allow your applications to store and load objects by converting them into a sequential stream of bytes (serialization).
System.Security
Contains classes that enable your application to control .NET Framework security features. These classes can manage security features such as permissions, policies, and cryptography.
System.ServiceProcess
Contains classes that allow your applications to create, install, and manage Windows services.
System.Text
Contains classes that represent ASCII, Unicode, UTF-7, and UTF-8 character sets.
System.Threading
Contains classes that enable you to develop multithreaded applications.
System.Timers
Contains classes that permit your application to raise an event following a specified interval of time.
System.Web
Contains a set of classes that define ASP.NET. These classes essentially provide support for Web browser to Web server interaction. For example, different classes contained in this Namespace support Web hosting, mail, security, and user interface components.
System.Windows.Forms
Contains the classes that enable the development of Windows-based applications.
System.Xml
Contains a set of classes that enable your application to work with XML documents.
Table 2-7.System Namespaces in the .NET Framework Class Library
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
Now that you've seen an overview of the different Namespaces that are included in the .NET Framework, it's time to look a little closer at the executable programs, or in .NET parlance, the assemblies that are created using the classes contained in those Namespaces. Assemblies are basically a new way of packaging executable code. Like the programs produced by earlier compilers, such as Visual C++, the assemblies that are created by the .NET compilers typically end with the file extension of .exe or .dll. However, unlike those programs that contain native x86 machine instructions, which can be directly executed by the Windows operating system, the assemblies output by the .NET compilers contain a combination of MSIL, metadata, and resources such as bitmaps. Assemblies cannot be executed without the presence of the .NET CLR. The metadata information that's stored in the assembly is known as the manifest, and it contains information about the resources within the assembly, as well as its dependencies. The Type metadata contain the CTS types that are used in the assembly. The executable code, or MSIL, is a platform-independent intermediate language that is a higher level than the native machine code produced by older compilers. Unlike standard x86 executable code, MSIL understands objects and has instructions that can instantiate and manipulate object properties. Similarly, MSIL contains facilities to raise and catch exceptions. Finally, the resources in an assembly typically contain the bitmaps, icons, and other binary resources that are used by the application. Figure 2-3 presents an overview of the internal stature of a single file assembly.
Unlike standard executable files, assemblies can be single file, or they can be contained in multiple files. For instance, an assembly could be split into three different files where one contained the metadata, another contained the MSIL, and another contained the resource and bitmaps used by the application. Multifile assemblies are typically used to support multiple-language applications. Figure 2-4 illustrates an example multifile assembly.
Figure 2-3. Sample single file assembly
In Figure 2-4, you can see that the code and resources are split between three different physical files. In this case, note that the manifest contained in the base MyAssembly.exe points to the other assemblies that are used. There are no Registry entries or other on-disk structures that are used to link together the different assembly components. The self-describing metadata is responsible for managing the assembly components. You'll find more information about the metadata contained in the assembly in the next section, "Assembly Manifest."
Figure 2-4.Sample multifile assembly
In addition to containing the executable program instructions, assemblies fulfill several important roles in the .NET Framework. First, assemblies define a security boundary. The assembly is the unit to which .NET permissions are granted. This security information enables a very granular level of security that was never possible with Win32 applications. .NET security can restrict and grant access at the function level of an application. Next, the assembly's manifest contains versioning information. This versioning information both identifies the current assembly and defines the version requirements for any required assemblies. Because each assembly carries with it its own version identification, as well as the version information of all dependent components, there is no possibility of an older version of a component or some otherwise incorrect but like-named component being accidentally installed and used. Next, the assembly limits the scope of the types contained in the assembly. Each type is contained within the bounds of its assembly. Identically named types in different assemblies are managed independently. Finally, an assembly forms the basic unit of deployment for a .NET application. When deploying a .NET application, you essentially just need to copy the assembly to the target system. The assembly's metadata is responsible for finding any required components.
When an assembly is created, it can be made as private or shared. Private assemblies can be used only by a single application, whereas shared assemblies can be used by multiple applications. Multiple versions of a given assembly can be simultaneously installed on the same machine. Assemblies can also be either static or dynamic. A static assembly resides in a PE (Portable Executable) file that's stored as an on-disk structure. A dynamic assembly is created and executed directly in memory, and it's not saved to disk.
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
The metadata in an assembly is called an assembly manifest, and it contains information about the types and resources that are externally visible outside the assembly. In addition, the metadata contains information about any dependencies that the assembly has. This includes information about dependent assembly names, their locations and their version number. Including the metadata information as a part of the assembly has a couple of important advantages. First, it finally eliminates the "DLL Hell" situation that continues to plague COM-based Windows applications; second, it frees the application from dependencies on the Windows Registry. "DLL Hell" describes an all-too-common error condition experienced by Windows applications where required new software installs inadvertently replace required application components such as DLLs with like-named components of a different version-which unfortunately are not completely compatible with the component they replace. When this happens, the new application typically works, but some existing application that depended on the old component broke. This was typically exacerbated by reinstalling the old software, which restored the original component and predictably broke the new application. Maintaining this versioning information in the metadata makes it possible to have side-by-side deployment where multiple versions of an assembly can be used simultaneously. Each assembly can load the dependent assemblies it needs without fear of using an incompatible component because the metadata specifies exactly which version of the component is required and where it is located. Because assemblies are self-describing, using the Registry isn't necessary to locate any of the dependent assemblies used in an application. Registering an assembly during installation is also unnecessary. This vastly simplifies the installation process and essentially enables xcopy style of deployment where assemblies can simply be copied to their destination system and executed. Table 2-8 presents the information that's contained in an assembly's manifest.
Item
Description
Assembly name
The assembly name.
Version number
The assembly's major and minor version number, and a revision and build number.
Culture
The region- and language-specific information about an assembly.
Strong name
The public key from the publisher for assemblies that use strong names. You can find more information about strong names in the "Assembly Security" section, later in this chapter.
List of all files
A list of all the files contained in the assembly and their filenames.
Type references
The information used by the CLR to map a type reference to the file that contains its declaration and implementation.
Referenced assemblies
List of assemblies that are statistically referenced by the current assembly. This list includes the assembly's name, metadata and public key, if the assembly is strong named.
Table 2-8.
Assembly Manifest Information
Viewing Assembly Metadata
You can view the contents of an assembly by using the Ildasm.exe tool that is supplied with the .NET Framework SDK. The Ildasm.exe tool is essentially an assembly disassembler. You run the Ildasm.exe utility by selecting Start | Programs | Microsoft Visual Studio.NET | Visual Studio .NET Tools | Visual Studio Command Prompt. From there, you can enter ILDASM followed by the path and name of the .NET assembly that you want to inspect. Figure 2-5 illustrates viewing an assembly's metadata using the ILDASM utility.
In Figure 2-5, you can see the assembly information for the ADONetSample application that accompanies this book. In the metadata information shown in the figure, you can see that the manifest information is listed at the top of the assembly followed by the information about the MSIL executable code in the assembly. Double-clicking the Manifest line displays the following metadata information, which lists the contents of the assembly including its name, external dependencies, and resources.
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
The Global Assembly Cache (GAC) is a .NET mechanism that's used to explicitly share assemblies between applications. As a rule, you should use the Global Assembly Cache only for assemblies that are expressly intended to be shared among multiple .NET applications. If your application's assembly is not shared, it should remain private, and you shouldn't add it to the Global Assembly Cache.
NOTE: If you place an application in the Global Assembly Cache, you can't subsequently deploy the application using xcopy because the GAC of the target system would need to be updated in order to execute the assembly.
You can view the GAC by using Windows Explorer and navigating to the %windows%assembly folder. An example of the GAC is shown in Figure 2-6.
.NET applications are added to the GAC by using a .NET-aware installer, or you can manually drag and drop files from Windows Explorer onto the Global Assembly Cache.
Figure 2-6.Viewing the Global Assembly Cache
Assembly Security
Assembly security is controlled by policies that are enforced by the CLR. When an assembly is executed, the CLR checks to ensure that the code about to be executed is allowed by the existing security polices. When the CLR first loads an assembly, it checks the available security policy to determine the assembly's permissions. In .NET parlance, the assembly security information is referred to as evidence. Evidence includes the assembly's publisher, its site, and its zone.
Setting Permissions
An administrator can set the security polices for a .NET application by using the .NET Framework Configuration tool, mscorcfg.msc, an MMC snap-in that's included with the .NET Framework. The permissions set by the .NET Framework Configuration tool are set after the application is deployed by an administrator, and they control the application's runtime behavior-they are not set during the development process. The .NET Framework Configuration tool can set security policies based on an enterprise-based policy, a machine-based policy, or a user-based policy. Table 2-9 lists the security configuration files that are modified using the .NET Framework Security Configuration tool.
You can start the by selecting Start | Programs | Microsoft Visual Studio.NET | Visual Studio .NET Tools | Visual Studio Command Prompt. From there, you can enter mscorcfg.msc at the command line. Figure 2-7 presents an example of the .NET Framework Configuration tool.
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.
In addition to setting an assembly's permissions, you can also sign the assembly to ensure its authenticity. There are two ways of signing an assembly. You can give an assembly a strong name and/or you can add a signcode digital signature to the assembly. Signing an assembly with a strong name adds a public key encryption to the assembly. Strong names ensure name uniqueness, and they are designed to prevent name spoofing. The strong name is stored in the file containing the assembly manifest. Signcode is a different and potentially complementary method of ensuring trust. No level of trust is associated with a strong name, whereas signcode does enable trusting code based on its publisher. Signcode is implemented using PKI and requires a publisher to prove their identity to a third-party authority and obtain a certificate. This certificate is then embedded in your assembly and can be used by the CLR to trust the code's authenticity. The signcode signature is stored in a reserved slot in the assembly. Signcode signing of an assembly is best used when you already have a trust hierarchy that's using signcode signatures.
Security Policy
Location
Enterprise
%runtime install path%ConfigEnterprisesec.config
Machine
%runtime install path%ConfigSecurity.config
User
%USERPROFILE%Application dataMicrosoftCLR security configvxx.xxSecurity.config (Windows 2000 and NT)
Figure 2-7.Using the .NET CFramework Configuration tool to set assembly security
Summary
In this chapter, you got a high-level overview of the .NET Framework. The .NET Framework, however, involves a lot more than you can fit into one chapter. In fact, several books have been written about it. For more detailed information about the .NET Framework, you can refer to Microsoft's .NET Framework Developer's Guide. In the next chapter, you'll get a closer look at the part of the .NET Framework that we database developer's really care about-namely, the System.Data Namespace, which provides the classes that make up ADO.NET.
This is chapter two of ADO.NET: The Complete Reference, by Michael and Denielle Otey (McGraw-Hill/Osborne, ISBN 0-07-222898-9, 2003). Check it out at your favorite bookstore today. Buy this book now.