Framework Overview - C# 5.0 in a Nutshell (2012)

C# 5.0 in a Nutshell (2012)

Chapter 5. Framework Overview

Almost all the capabilities of the .NET Framework are exposed via a vast set of managed types. These types are organized into hierarchical namespaces and packaged into a set of assemblies, which together with the CLR comprise the .NET platform.

Some of the .NET types are used directly by the CLR and are essential for the managed hosting environment. These types reside in an assembly called mscorlib.dll and include C#’s built-in types, as well as the basic collection classes, types for stream processing, serialization, reflection, threading, and native interoperability (“mscorlib” is an abbreviation for Multi-language Standard Common Object Runtime Library”).

At a level above this are additional types that “flesh out” the CLR-level functionality, providing features such as XML, networking, and LINQ. These reside in System.dll, System.Xml.dll, and System.Core.dll, and together with mscorlib they provide a rich programming environment upon which the rest of the Framework is built. This “core framework” largely defines the scope of the rest of this book.

The remainder of the .NET Framework consists of applied APIs, most of which cover three areas of functionality:

§ User interface technologies

§ Backend technologies

§ Distributed system technologies

Table 5-1 shows the history of compatibility between each version of C#, the CLR, and the .NET Framework. C# 5.0 targets CLR 4.5 which is unusual because it’s a patched version of CLR 4.0. This means that applications targeting CLR 4.0 will actually run on CLR 4.5 after you install the latter; hence Microsoft has taken extreme care to ensure backward compatibility.

Table 5-1. C#, CLR, and .NET Framework versions

C# version

CLR version

Framework versions

1.0

1.0

1.0

1.2

1.1

1.1

2.0

2.0

2.0, 3.0

3.0

2.0 (SP1)

3.5

4.0

4.0

4.0

5.0

4.5 (Patched CLR 4.0)

4.5

This chapter skims all key areas of the .NET Framework—starting with the core types covered in this book and finishing with an overview of the applied technologies.

NOTE

Assemblies and namespaces in the .NET Framework cross-cut. The most extreme examples are mscorlib.dll and System.Core.dll, both defining types in dozens of namespaces, none of which is prefixed with mscorlib or System.Core. The less obvious cases are the more confusing ones, however, such as the types in System.Security.Cryptography. Most types in this namespace reside in System.dll, except for a handful, which reside in System.Security.dll. The book’s companion website contains a complete mapping of Framework namespaces to assemblies (http://www.albahari.com/nutshell/namespacereference.aspx).

WHAT’S NEW IN .NET FRAMEWORK 4.5

New features of Framework 4.5 include:

§ Extensive support for asynchrony through Task-returning methods

§ Support for the zip compression protocol (Chapter 15)

§ Improved HTTP support through the new HttpClient class (Chapter 16)

§ Performance improvements to the garbage collector and assembly resource retrieval

§ Support for WinRT interoperability and APIs for building Metro-style tablet apps

There’s also a new TypeInfo class (Chapter 19) and the ability to specify timeouts when matching regular expression timeouts (Chapter 26).

In the Parallel Computing space, there’s a specialized new library called Dataflow for building producer/consumer-style networks.

There have also been improvements to the WPF, WCF and WF (Workflow Foundation) libraries.

Many of the core types are defined in the following assemblies: mscorlib.dll, System.dll, and System.Core.dll. The first of these, mscorlib.dll, comprises the types required by the runtime environment itself; System.dll and System.Core.dll contain additional core types required by you as a programmer. The reason the latter two are separate is historical: when the Microsoft team introduced Framework 3.5, they made it additive insofar as it ran over the existing CLR 2.0 (just as Framework 4.5 is additive over 4.0). Therefore, almost all new core types (such as the classes supporting LINQ) went into a new assembly which Microsoft called System.Core.dll.

WHAT’S NEW IN .NET FRAMEWORK 4.0

Framework 4.0 added the following:

§ New core types: BigInteger (for arbitrarily large numbers), Complex (complex numbers), and tuples (Chapter 6)

§ A new SortedSet collection (Chapter 7)

§ Code contracts, for enabling methods to interact more reliably through mutual obligations and responsibilities (Chapter 13)

§ Direct support for memory-mapped files (Chapter 15)

§ Lazy file- and directory-I/O methods that return IEnumerable<T> instead of arrays (Chapter 15)

§ The Dynamic Language Runtime (DLR), which is now part of the .NET Framework (Chapter 20)

§ Security transparency, which makes it easier to secure libraries in partially trusted environments (Chapter 21)

§ New threading constructs, including a more robust Monitor.Enter overload, Thread.Yield, new signaling classes (Barrier and CountdownEvent), and lazy initialization primitives (Chapter 22)

§ Parallel programming APIs for leveraging multicore processors, including Parallel LINQ (PLINQ), imperative data and task parallelism constructs, concurrent collections, and low-latency synchronization and spinning primitives (Chapter 23)

§ Methods for application domain resource monitoring (Chapter 24)

Framework 4.0 also contained enhancements to ASP.NET, including the MVC framework and Dynamic Data, and enhancements to Entity Framework, WPF, WCF, and Workflow. In addition, it included the Managed Extensibility Framework library, to assist with runtime composition, discovery, and dependency injection.

The CLR and Core Framework

System Types

The most fundamental types live directly in the System namespace. These include C#’s built-in types, the Exception base class, the Enum, Array, and Delegate base classes, and Nullable, Type, DateTime, TimeSpan, and Guid. The System namespace also includes types for performing mathematical functions (Math), generating random numbers (Random), and converting between various types (Convert and BitConverter).

Chapter 6 describes these types—as well as the interfaces that define standard protocols used across the .NET Framework for such tasks as formatting (IFormattable) and order comparison (IComparable).

The System namespace also defines the IDisposable interface and the GC class for interacting with the garbage collector. These topics are saved for Chapter 12.

Text Processing

The System.Text namespace contains the StringBuilder class (the editable or mutable cousin of string), and the types for working with text encodings, such as UTF-8 (Encoding and its subtypes). We cover this in Chapter 6.

The System.Text.RegularExpressions namespace contains types that perform advanced pattern-based search and replace operations; these are described in Chapter 26.

Collections

The .NET Framework offers a variety of classes for managing collections of items. These include both list- and dictionary-based structures, and work in conjunction with a set of standard interfaces that unify their common characteristics. All collection types are defined in the following namespaces, covered in Chapter 7:

System.Collections // Nongeneric collections

System.Collections.Generic // Generic collections

System.Collections.Specialized // Strongly typed collections

System.Collections.ObjectModel // Bases for your own collections

System.Collections.Concurrent // Thread-safe collection (Chapter 23)

Queries

Language Integrated Query (LINQ) was added in Framework 3.5. LINQ allows you to perform type-safe queries over local and remote collections (e.g., SQL Server tables) and is described in Chapter 8 through Chapter 10. A big advantage of LINQ is that it presents a consistent querying API across a variety of domains. The types for resolving LINQ queries reside in these namespaces:

System.Linq // LINQ to Objects and PLINQ

System.Linq.Expressions // For building expressions manually

System.Xml.Linq // LINQ to XML

The full .NET profile also includes the following:

System.Data.Linq // LINQ to SQL

System.Data.Entity // LINQ to Entities (Entity Framework)

(The Metro profile excludes the entire System.Data.* namespace.)

The LINQ to SQL and Entity Framework APIs leverage lower-level ADO.NET types in the System.Data namespace.

XML

XML is used widely within the .NET Framework, and so is supported extensively. Chapter 10 focuses entirely on LINQ to XML—a lightweight XML document object model that can be constructed and queried through LINQ. Chapter 11 describes the older W3C DOM, as well as the performant low-level reader/writer classes and the Framework’s support for XML schemas, stylesheets, and XPath. The XML namespaces are:

System.Xml // XmlReader, XmlWriter + the old W3C DOM

System.Xml.Linq // The LINQ to XML DOM

System.Xml.Schema // Support for XSD

System.Xml.Serialization // Declarative XML serialization for .NET types

The following namespaces are available in the standard .NET profiles (but not Metro):

System.Xml.XPath // XPath query language

System.Xml.Xsl // Stylesheet support

Diagnostics and Code Contracts

In Chapter 13, we cover .NET’s logging and assertion facilities and the code contracts system which was introduced in Framework 4.0. We also describe how to interact with other processes, write to the Windows event log, and use performance counters for monitoring. The types for this are defined in and under System.Diagnostics.

Concurrency and Asynchrony

Most modern applications need to deal with more than one thing happening at a time. C# 5.0 and Framework 4.5 make this easier than in the past through asynchronous functions and high-level constructs such as tasks and task combinators. Chapter 14 explains all of this in detail, after starting with the basics of multithreading. Types for working with threads and asynchronous operations are in the System.Threading and System.Threading.Tasks namespaces.

Streams and I/O

The Framework provides a stream-based model for low-level input/output. Streams are typically used to read and write directly to files and network connections, and can be chained or wrapped in decorator streams to add compression or encryption functionality. Chapter 15 describes .NET’s stream architecture, as well as the specific support for working with files and directories, compression, isolated storage, pipes, and memory-mapped files. The .NET Stream and I/O types are defined in and under the System.IO namespace, and the WinRT types for file I/O are in and underWindows.Storage.

Networking

You can directly access standard network protocols such as HTTP, FTP, TCP/IP, and SMTP via the types in System.Net. In Chapter 16, we demonstrate how to communicate using each of these protocols, starting with simple tasks such as downloading from a web page, and finishing with using TCP/IP directly to retrieve POP3 email. Here are the namespaces we cover:

System.Net

System.Net.Http // HttpClient

System.Net.Mail // For sending mail via SMTP

System.Net.Sockets // TCP, UDP, and IP

The latter two namespaces are not available to Metro applications, which must instead use WinRT types for these functions.

Serialization

The Framework provides several systems for saving and restoring objects to a binary or text representation. Such systems are required for distributed application technologies, such as WCF, Web Services, and Remoting, and also to save and restore objects to a file. In Chapter 17, we cover all three serialization engines: the data contract serializer, the binary serializer, and the XML serializer. The types for serialization reside in the following namespaces:

System.Runtime.Serialization

System.Xml.Serialization

The Metro profile excludes the binary serialization engine.

Assemblies, Reflection, and Attributes

The assemblies into which C# programs compile comprise executable instructions (stored as intermediate language or IL) and metadata, which describes the program’s types, members, and attributes. Through reflection, you can inspect this metadata at runtime, and do such things as dynamically invoke methods. With Reflection.Emit, you can construct new code on the fly.

In Chapter 18, we describe the makeup of assemblies and how to sign them, use the global assembly cache and resources, and resolve file references. In Chapter 19, we cover reflection and attributes—describing how to inspect metadata, dynamically invoke functions, write custom attributes, emit new types, and parse raw IL. The types for using reflection and working with assemblies reside in the following namespaces:

System

System.Reflection

System.Reflection.Emit (not in Metro profile)

Dynamic Programming

In Chapter 20, we look at some of the patterns for dynamic programming and leveraging the Dynamic Language Runtime, which has been a part of the CLR since Framework 4.0. We describe how to implement the Visitor pattern, write custom dynamic objects, and interoperate with IronPython. The types for dynamic programming are in System.Dynamic.

Security

The .NET Framework provides its own security layer, allowing you to both sandbox other assemblies and be sandboxed yourself. In Chapter 21, we cover code access, role, and identity security, and the transparency model introduced in CLR 4.0. We then describe cryptography in the Framework, covering encryption, hashing, and data protection. The types for this are defined in:

System.Security

System.Security.Permissions

System.Security.Policy

System.Security.Cryptography

Only System.Security is available in the Metro profile; cryptography is handled instead in WinRT.

Advanced Threading

C# 5’s asynchronous functions make concurrent programming significantly easier because they lessen the need for lower-level techniques. However, there are still times when you need signaling constructs, thread-local storage, reader/writer locks, and so on. Chapter 22 explains this in depth. Threading types are in the System.Threading namespace.

Parallel Programming

In Chapter 23, we cover in detail the libraries and types for leveraging multicore processors, including APIs for task parallelism, imperative data parallelism and functional parallelism (PLINQ).

Application Domains

The CLR provides an additional level of isolation within a process, called an application domain. In Chapter 24, we examine the properties of an application domain with which you can interact, and demonstrate how to create and use additional application domains within the same process for such purposes as unit testing. We also describe how to use Remoting to communicate with these application domains. The AppDomain type is defined in the System namespace is applicable only to non-Metro apps.

Native and COM Interoperability

You can interoperate with both native and COM code. Native interoperability allows you to call functions in unmanaged DLLs, register callbacks, map data structures, and interoperate with native data types. COM interoperability allows you to call COM types and expose .NET types to COM. The types that support these functions are in System.Runtime.InteropServices, and we cover them in Chapter 25.

Applied Technologies

User Interface Technologies

The .NET Framework provides four APIs for user interface–based applications:

ASP.NET (System.Web.UI)

For writing thin client applications that run over a standard web browser

Silverlight

For providing a rich user interface inside a web browser

Windows Presentation Foundation (System.Windows)

For writing rich client applications

Windows Forms (System.Windows.Forms)

For maintaining legacy rich client applications

In general, a thin client application amounts to a website; a rich client application is a program the end user must download or install on the client computer.

ASP.NET

Applications written using ASP.NET host under Windows IIS and can be accessed from almost any web browser. Here are the advantages of ASP.NET over rich client technologies:

§ There is zero deployment at the client end.

§ Clients can run a non-Windows platform.

§ Updates are easily deployed.

Further, because most of what you write in an ASP.NET application runs on the server, you design your data access layer to run in the same application domain—without limiting security or scalability. In contrast, a rich client that does the same is not generally as secure or scalable. (The solution, with the rich client, is to insert a middle tier between the client and database. The middle tier runs on a remote application server [often alongside the database server] and communicates with the rich clients via WCF, Web Services, or Remoting.)

In writing your web pages, you can choose between the traditional Web Forms and the new MVC (Model-View-Controller) API. Both build on the ASP.NET infrastructure. Web Forms has been part of the Framework since its inception; MVC was written much later in response to the success of Ruby on Rails and MonoRail. Although debuting in Framework 4.0, the MVC framework has benefited from having matured for some time as a public beta. It provides, in general, a better programming abstraction than Web Forms; it also allows more control over the generated HTML. What you lose over Web Forms is a designer. This makes Web Forms still a good choice for web pages with predominately static content.

The limitations of ASP.NET are largely a reflection of the limitations of thin client systems in general:

§ A web browser interface significantly restricts what you can do.

§ Maintaining state on the client—or on behalf of the client—is cumbersome.

You can improve the interactivity and responsiveness, however, through client-side scripting or technologies such as AJAX: a good resource for this is http://ajax.asp.net. Use of AJAX is simplified through the use of libraries such as jQuery.

The types for writing ASP.NET applications are in the System.Web.UI namespace and its subnamespaces, and are packed in the System.Web.dll assembly.

Silverlight

Silverlight is not technically part of the main .NET Framework: it’s a separate Framework that includes a subset of the Framework’s core features—plus the ability to run as a web browser plug-in. Its graphics model is essentially a subset of WPF and this allows you to leverage existing knowledge in developing Silverlight applications. Silverlight is available as a small cross-platform download for web browsers—much like Macromedia’s Flash.

Flash has a far bigger installation base and so dominates in this area. For this reason, Silverlight tends to be used in fringe scenarios—corporate intranets, for example.

Metro

Also not part of the.NET Framework, the Windows “Metro” library is for developing tablet user interfaces in Windows 8 (see C# and Windows Runtime in Chapter 1). The Metro API was inspired by WPF and uses XAML for layout. The namespaces are Windows.UI andWindows.UI.Xaml.

Windows Presentation Foundation (WPF)

WPF was introduced in Framework 3.0 for writing rich client applications. The benefits of WPF over its predecessor, Windows Forms, are as follows:

§ It supports sophisticated graphics, such as arbitrary transformations, 3D rendering, and true transparency.

§ Its primary measurement unit is not pixel-based, so applications display correctly at any DPI (dots per inch) setting.

§ It has extensive dynamic layout support, which means you can localize an application without danger of elements overlapping.

§ Rendering uses DirectX and is fast, taking good advantage of graphics hardware acceleration.

§ User interfaces can be described declaratively in XAML files that can be maintained independently of the “code-behind” files—this helps to separate appearance from functionality.

WPF’s size and complexity, however, make for a steep learning curve.

The types for writing WPF applications are in the System.Windows namespace and all subnamespaces except for System.Windows.Forms.

Windows Forms

Windows Forms is a rich client API that’s as old as the .NET Framework. Compared to WPF, Windows Forms is a relatively simple technology that provides most of the features you need in writing a typical Windows application. It also has significant relevancy in maintaining legacy applications. It has a number of drawbacks, though, compared to WPF:

§ Controls are positioned and sized in pixels, making it easy to write applications that break on clients whose DPI settings differ from the developer’s.

§ The API for drawing nonstandard controls is GDI+, which, although reasonably flexible, is slow in rendering large areas (and without double buffering, may flicker).

§ Controls lack true transparency.

§ Dynamic layout is difficult to get right reliably.

The last point is an excellent reason to favor WPF over Windows Forms—even if you’re writing a business application that needs just a user interface and not a “user experience.” The layout elements in WPF, such as Grid, make it easy to assemble labels and text boxes such that they always align—even after language changing localization—without messy logic and without any flickering. Further, you don’t have to bow to the lowest common denominator in screen resolution—WPF layout elements have been designed from the outset to adapt properly to resizing.

On the positive side, Windows Forms is relatively simple to learn and still has a wealth of support in third-party controls.

The Windows Forms types are in the System.Windows.Forms (in System.Windows.Forms.dll) and System.Drawing (in System.Drawing.dll) namespaces. The latter also contains the GDI+ types for drawing custom controls.

Backend Technologies

ADO.NET

ADO.NET is the managed data access API. Although the name is derived from the 1990s-era ADO (ActiveX Data Objects), the technology is completely different. ADO.NET contains two major low-level components:

Provider layer

The provider model defines common classes and interfaces for low-level access to database providers. These interfaces comprise connections, commands, adapters, and readers (forward-only, read-only cursors over a database). The Framework ships with native support for Microsoft SQL Server and Oracle and has OLE-DB and ODBC providers.

DataSet model

A DataSet is a structured cache of data. It resembles a primitive in-memory database, which defines SQL constructs such as tables, rows, columns, relationships, constraints, and views. By programming against a cache of data, you can reduce the number of trips to the server, increasing server scalability and the responsiveness of a rich-client user interface. DataSets are serializable and are designed to be sent across the wire between client and server applications.

Sitting above the provider layer are two APIs that offer the ability to query databases via LINQ:

§ LINQ to SQL (introduced in Framework 3.5)

§ Entity Framework (introduced in Framework 3.5 SP1)

Both technologies include object/relational mappers (ORMs), meaning they automatically map objects (based on classes that you define) to rows in the database. This allows you to query those objects via LINQ (instead of writing SQL select statements)—and update them without manually writing SQL insert/delete/update statements. This cuts the volume of code in an application’s data access layer (particularly the “plumbing” code) and provides strong static type safety. These technologies also avoid the need for DataSets as receptacles of data—although DataSets still provide the unique ability to store and serialize state changes (something particularly useful in multitier applications). You can use LINQ to SQL or Entity Framework in conjunction with DataSets, although the process is somewhat clumsy and DataSets are inherently ungainly. In other words, there’s no straightforward out-of-the-box solution for writing n-tier applications with Microsoft’s ORMs as yet.

LINQ to SQL is simpler and faster than Entity Framework, and tends to produce better SQL (although Entity Framework has improved in later versions). Entity Framework is more flexible in that you can create elaborate mappings between the database and the classes that you query, and offers a model that allows third-party support for databases other than SQL Server.

Windows Workflow

Windows Workflow is a framework for modeling and managing potentially long-running business processes. Workflow targets a standard runtime library, providing consistency and interoperability. Workflow also helps reduce coding for dynamically controlled decision-making trees.

Windows Workflow is not strictly a backend technology—you can use it anywhere (an example is page flow, in the UI).

Workflow came originally with .NET Framework 3.0, with its types defined in the System.WorkFlow namespace. Workflow was substantially revised in Framework 4.0; the new types live in and under the System.Activities namespace.

COM+ and MSMQ

The Framework allows you to interoperate with COM+ for services such as distributed transactions, via types in the System.EnterpriseServices namespace. It also supports MSMQ (Microsoft Message Queuing) for asynchronous, one-way messaging through types inSystem.Messaging.

Distributed System Technologies

Windows Communication Foundation (WCF)

WCF is a sophisticated communications infrastructure introduced in Framework 3.0. WCF is flexible and configurable enough to make both of its predecessors—Remoting and (.ASMX) Web Services—mostly redundant.

WCF, Remoting, and Web Services are all alike in that they implement the following basic model in allowing a client and server application to communicate:

§ On the server, you indicate what methods you’d like remote client applications to be able to call.

§ On the client, you specify or infer the signatures of the server methods you’d like to call.

§ On both the server and the client, you choose a transport and communication protocol (in WCF, this is done through a binding).

§ The client establishes a connection to the server.

§ The client calls a remote method, which executes transparently on the server.

WCF further decouples the client and server through service contracts and data contracts. Conceptually, the client sends an (XML or binary) message to an endpoint on a remote service, rather than directly invoking a remote method. One of the benefits of this decoupling is that clients have no dependency on the .NET platform or on any proprietary communication protocols.

WCF is highly configurable and provides the most extensive support for standardized messaging protocols, including WS-*. This lets you communicate with parties running different software—possibly on different platforms—while still supporting advanced features such as encryption. Another benefit of WCF is that you can change protocols without needing to change other aspects of your client or server applications.

The types for communicating with WCF are in, and below, the System.ServiceModel namespace.

Remoting and .ASMX Web Services

Remoting and .ASMX Web Services are WCF’s predecessors and are almost redundant in WCF’s wake—although Remoting still has a niche in communicating between application domains within the same process (see Chapter 24).

Remoting’s functionality is geared toward tightly coupled applications. A typical example is when the client and server are both .NET applications written by the same company (or companies sharing common assemblies). Communication typically involves exchanging potentially complex custom .NET objects that the Remoting infrastructure serializes and deserializes without needing intervention.

The functionality of Web Services is geared toward loosely coupled or SOA-style applications. A typical example is a server designed to accept simple SOAP-based messages that originate from clients running a variety of software—on a variety of platforms. Web Services can only useHTTP and SOAP as transport and formatting protocols, and applications are normally hosted under IIS. The benefits of interoperability come at a performance cost—a Web Services application is typically slower, in both execution and development time, than a well-designed Remoting application.

The types for Remoting are in or under System.Runtime.Remoting; the types for Web Services are under System.Web.Services.

CardSpace

CardSpace is a token-based authentication and identity management protocol designed to simplify password management for end users. The technology has received little attention because of the difficulty in porting tokens across machines (OpenID is a popular alternative that avoids this problem).

CardSpace builds on open XML standards, and parties can participate independently of Microsoft. A user can hold multiple identities, which are maintained by a third party (the identity provider). When a user wants to access a resource at site X, the user authenticates to the identity provider, which then issues a token to site X. This avoids having to provide a password directly to site X and reduces the number of identities that the user needs to maintain.

WCF allows you to specify a CardSpace identity when connecting through a secure HTTP channel, through types in the System.IdentityModel.Claims and System.IdentityModel.Policy namespaces.