You are previewing Programming .NET Components, 2nd Edition.
O'Reilly logo
Programming .NET Components, 2nd Edition

Book Description

Brilliantly compiled by author Juval Lowy, Programming .NET Components, Second Edition is the consummate introduction to the Microsoft .NET Framework--the technology of choice for building components on Windows platforms. From its many lessons, tips, and guidelines, readers will learn how to use the .NET Framework to program reusable, maintainable, and robust components. Following in the footsteps of its best-selling predecessor, Programming .NET Components, Second Edition has been updated to cover .NET 2.0. It remains one of the few practical books available on this topic. This invaluable resource is targeted at anyone who develops complex or enterprise-level applications with the .NET platform--an ever-widening market. In fact, nearly two million Microsoft developers worldwide now work on such systems. Programming .NET Components, Second Edition begins with a look at the fundamentals of component-oriented programming and then progresses from there. It takes the time to carefully examine how components can simplify and add flexibility to complex applications by allowing users to extend their capabilities. Next, the book introduces a variety of .NET essentials, as well as .NET development techniques. Within this discussion on component development, a separate chapter is devoted to each critical development feature, including asynchronous calls, serialization, remoting, security, and more. All the while, hazardous programming pitfalls are pointed out, saving the reader from experiencing them the hard way. A .NET expert and noted authority on component-oriented programming, Lowy uses his unique access to Microsoft technical teams to the best possible advantage, conveying detailed, insider information in easy-to-grasp, activity-filled language. This hands-on approach is designed to allow individuals to learn by doing rather than just reading. Indeed, after digesting Programming .NET Components, Second Edition, readers should be able to start developing .NET components immediately. Programming .NET Components, Second Edition is the consummate introduction to the Microsoft .NET Framework--the technology of choice for building components on Windows platforms. From its many lessons, tips, and guidelines, readers will learn how to use the .NET Framework to program reusable, maintainable, and robust components. Following in the footsteps of its best-selling predecessor, Programming .NET Components, Second Edition has been updated to cover .NET 2.0. This invaluable resource is targeted at anyone who develops complex or enterprise-level applications with the .NET platform--an ever-widening market.

Table of Contents

  1. Programming .NET Components, 2nd Edition
  2. Dedication
  3. A Note Regarding Supplemental Files
  4. Preface
    1. Scope of This Book
    2. Some Assumptions About the Reader
    3. Conventions Used in This Book
    4. Comments and Questions
    5. Safari Enabled
    6. Acknowledgments
  5. 1. Introducing Component-Oriented Programming
    1. 1.1. Basic Terminology
    2. 1.2. Component-Oriented Versus Object-Oriented Programming
      1. 1.2.1. Building Blocks Versus Monolithic Applications
      2. 1.2.2. Interfaces Versus Inheritance
    3. 1.3. Principles of Component-Oriented Programming
      1. 1.3.1. Separation of Interface from Implementation
      2. 1.3.2. Binary Compatibility Between Client and Server
      3. 1.3.3. Language Independence
      4. 1.3.4. Location Transparency
      5. 1.3.5. Concurrency Management
      6. 1.3.6. Versioning Support
      7. 1.3.7. Component-Based Security
    4. 1.4. .NET Adherence to Component Principles
    5. 1.5. Developing .NET Components
      1. 1.5.1. The .NET Base Classes
      2. 1.5.2. Declarative Programming
      3. 1.5.3. Component-Oriented Security
      4. 1.5.4. Simplified Deployment
  6. 2. .NET Component-Oriented Programming Essentials
    1. 2.1. Language Independence: The CLR
      1. 2.1.1. Intermediate Language and the JIT Compiler
      2. 2.1.2. .NET Programming Languages
      3. 2.1.3. .NET Components Are Language-Independent
      4. 2.1.4. Choosing a .NET Language
    2. 2.2. Packaging and Deployment: Assemblies
      1. 2.2.1. DLLs and COM Components
      2. 2.2.2. .NET Assemblies
      3. 2.2.3. Assemblies and Visual Studio 2005
        1. 2.2.3.1. Partial types
        2. 2.2.3.2. Adding a reference
        3. 2.2.3.3. The reference path
        4. 2.2.3.4. Aliasing a reference
        5. 2.2.3.5. The Visual Studio 2005 assembly host
      4. 2.2.4. Client and Server Assemblies
      5. 2.2.5. Managing Component Visibility in Assemblies
      6. 2.2.6. Assembly Metadata
      7. 2.2.7. The Assembly Manifest
      8. 2.2.8. Friend Assemblies
      9. 2.2.9. Composing Assemblies
      10. 2.2.10. The Assembly Type
    3. 2.3. Binary Compatibility
      1. 2.3.1. COM Binary Compatibility
      2. 2.3.2. .NET Binary Compatibility
      3. 2.3.3. Binary Inheritance
  7. 3. Interface-Based Programming
    1. 3.1. Separating Interface from Implementation
      1. 3.1.1. Interface Implementation
      2. 3.1.2. Explicit Interface Implementation
    2. 3.2. Working with Interfaces
      1. 3.2.1. Interfaces and Type Safety
      2. 3.2.2. Interface Methods, Properties, and Events
      3. 3.2.3. Interfaces and Structs
      4. 3.2.4. Interfaces and Partial Types
      5. 3.2.5. Implementing Multiple Interfaces
      6. 3.2.6. Interfaces and Class Hierarchies
    3. 3.3. Interfaces and Generics
      1. 3.3.1. Deriving from a Generic Interface
      2. 3.3.2. Explicit Generic Interface Implementation
      3. 3.3.3. Generic Interfaces as Operators
      4. 3.3.4. Interface-Level Constraints
      5. 3.3.5. Generic Derivation Constraints
      6. 3.3.6. Generics, Interfaces, and Casting
      7. 3.3.7. Generic Interface Methods
    4. 3.4. Designing and Factoring Interfaces
      1. 3.4.1. Interface Factoring
      2. 3.4.2. Factoring Metrics
    5. 3.5. Interfaces in Visual Studio 2005
      1. 3.5.1. Interface Refactoring
  8. 4. Lifecycle Management
    1. 4.1. The Managed Heap
    2. 4.2. Traditional Memory De-allocation Schemas
    3. 4.3. .NET Garbage Collection
    4. 4.4. Object Finalization
      1. 4.4.1. Explicit Garbage Collection
      2. 4.4.2. Finalize() Method Implementation
    5. 4.5. Deterministic Finalization
      1. 4.5.1. The Open/Close Pattern
      2. 4.5.2. The Dispose() Pattern
      3. 4.5.3. The IDisposable Pattern
      4. 4.5.4. Disposing and Error Handling
        1. 4.5.4.1. The using statement and interfaces
        2. 4.5.4.2. The using statements and generics
      5. 4.5.5. Dispose() and Finalize()
      6. 4.5.6. Deterministic Finalization Template
  9. 5. Versioning
    1. 5.1. Assembly Version Number
      1. 5.1.1. Version Number Elements
      2. 5.1.2. Providing the Version Number
    2. 5.2. Assembly Deployment Models
    3. 5.3. Strong Assembly Names
      1. 5.3.1. Signing Your Assembly
        1. 5.3.1.1. Generating a strong name key file
        2. 5.3.1.2. Selecting an existing strong name key file
        3. 5.3.1.3. Handling large organizations' keys
      2. 5.3.2. Strong Names and Private Assemblies
      3. 5.3.3. Friend Assemblies and Strong Names
      4. 5.3.4. Installing a Shared Assembly
        1. 5.3.4.1. Verifying shared assembly mode
        2. 5.3.4.2. Side-by-side execution
    4. 5.4. Visual Studio 2005 and Versioning
      1. 5.4.1. Specific Reference Version
    5. 5.5. Custom Version Policies
      1. 5.5.1. Application Custom Policies
        1. 5.5.1.1. Custom version-binding policies
        2. 5.5.1.2. Custom codebase policies
        3. 5.5.1.3. Application configuration file
      2. 5.5.2. Global Custom Policies
    6. 5.6. CLR Versioning
      1. 5.6.1. CLR Side-by-Side Execution
      2. 5.6.2. Version Unification
      3. 5.6.3. Specifying a CLR Version
        1. 5.6.3.1. Default version binding
        2. 5.6.3.2. Specifying supported CLR versions
  10. 6. Events
    1. 6.1. Delegate-Based Events
      1. 6.1.1. Delegate Inference
      2. 6.1.2. Generic Delegates
      3. 6.1.3. The event Keyword
      4. 6.1.4. Events in Visual Basic 2005
    2. 6.2. Working with .NET Events
      1. 6.2.1. Defining Delegate Signatures
      2. 6.2.2. Defining Custom Event Arguments
      3. 6.2.3. The Generic Event Handler
      4. 6.2.4. Publishing Events Defensively
        1. 6.2.4.1. The EventsHelper class
        2. 6.2.4.2. Making EventsHelper type-safe
      5. 6.2.5. Event Accessors
      6. 6.2.6. Managing Large Numbers of Events
      7. 6.2.7. Writing Sink Interfaces
  11. 7. Asynchronous Calls
    1. 7.1. Requirements for an Asynchronous Mechanism
    2. 7.2. Revisiting Delegates
    3. 7.3. Asynchronous Call Programming Models
      1. 7.3.1. Using BeginInvoke() and EndInvoke()
        1. 7.3.1.1. The IAsyncResult interface
        2. 7.3.1.2. The AsyncResult class
        3. 7.3.1.3. Polling or waiting for completion
      2. 7.3.2. Using Completion Callback Methods
        1. 7.3.2.1. Callback methods and thread safety
        2. 7.3.2.2. Passing state information
      3. 7.3.3. Performing Asynchronous Operations Without Delegates
    4. 7.4. Asynchronous Error Handling
    5. 7.5. Asynchronous Events
      1. 7.5.1. Asynchronous EventsHelper
        1. 7.5.1.1. Type-safe asynchronous EventsHelper
    6. 7.6. Asynchronous Invocation Pitfalls
      1. 7.6.1. Threading Concurrency and Synchronization
      2. 7.6.2. Thread-Pool Exhaustion
      3. 7.6.3. Premature Access by Reference and Reference Types
      4. 7.6.4. Lengthy Constructors
      5. 7.6.5. Cleaning Up After EndInvoke
    7. 7.7. Synchronous Versus Asynchronous Processing
  12. 8. Multithreading and Concurrency Management
    1. 8.1. Threads and Multithreading
    2. 8.2. Components and Threads
    3. 8.3. Working with Threads
      1. 8.3.1. Creating Threads
        1. 8.3.1.1. Designing thread methods
      2. 8.3.2. Blocking Threads
        1. 8.3.2.1. Suspending and resuming a thread
        2. 8.3.2.2. Putting a thread to sleep
        3. 8.3.2.3. Spinning while waiting
        4. 8.3.2.4. Joining a thread
        5. 8.3.2.5. Interrupting a waiting thread
      3. 8.3.3. Aborting a Thread
      4. 8.3.4. Thread States
      5. 8.3.5. Foreground and Background Threads
      6. 8.3.6. Thread Priority and Scheduling
    4. 8.4. Synchronizing Threads
    5. 8.5. Automatic Synchronization
      1. 8.5.1. Synchronization Domains
      2. 8.5.2. Synchronization Domains and Contexts
      3. 8.5.3. Configuring Synchronization Domains
        1. 8.5.3.1. Synchronization NOT_SUPPORTED
        2. 8.5.3.2. Synchronization SUPPORTED
        3. 8.5.3.3. Synchronization REQUIRED
        4. 8.5.3.4. Synchronization REQUIRES_NEW
        5. 8.5.3.5. Choosing between REQUIRED and REQUIRES_NEW
      4. 8.5.4. Synchronization-Domain Reentrancy
      5. 8.5.5. Synchronization Domain Pros and Cons
    6. 8.6. Manual Synchronization
      1. 8.6.1. The Monitor
        1. 8.6.1.1. Protecting static members and methods
        2. 8.6.1.2. Error handling
        3. 8.6.1.3. Encapsulating Monitor
        4. 8.6.1.4. Thread-safe structures
        5. 8.6.1.5. Monitor and generics
        6. 8.6.1.6. Synchronized methods
        7. 8.6.1.7. Waiting and signaling with Monitor
      2. 8.6.2. Waitable Handles
        1. 8.6.2.1. Using WaitHandle
        2. 8.6.2.2. WaitHandle versus Monitor
      3. 8.6.3. The Mutex
        1. 8.6.3.1. Using a mutex
        2. 8.6.3.2. Named mutexes
      4. 8.6.4. Waitable Events
        1. 8.6.4.1. Manual-reset events
        2. 8.6.4.2. Auto-reset events
        3. 8.6.4.3. Waitable events versus monitors
        4. 8.6.4.4. Thread rendezvous example
      5. 8.6.5. The Semaphore
      6. 8.6.6. The Interlocked
      7. 8.6.7. The Reader/Writer Lock
    7. 8.7. The WorkerThread Wrapper Class
      1. 8.7.1. Launching a New Worker Thread
      2. 8.7.2. Joining WorkerThread and the Thread Handle
      3. 8.7.3. Terminating the Worker Thread
    8. 8.8. Synchronizing Delegates
    9. 8.9. Using .NET Multithreading Services
      1. 8.9.1. Thread-Relative Static Variables
      2. 8.9.2. Thread Local Storage
        1. 8.9.2.1. Using a named slot
        2. 8.9.2.2. Using an unnamed slot
      3. 8.9.3. The Thread Pool
        1. 8.9.3.1. Configuring the thread pool
      4. 8.9.4. ISynchronizeInvoke
        1. 8.9.4.1. Using ISynchronizeInvoke
        2. 8.9.4.2. Windows Forms and ISynchronizeInvoke
        3. 8.9.4.3. Events and ISynchronizeInvoke
        4. 8.9.4.4. Implementing ISynchronizeInvoke
      5. 8.9.5. Windows Forms and Asynchronous Calls
        1. 8.9.5.1. Web service proxy classes
      6. 8.9.6. Timers
        1. 8.9.6.1. System.Timers.Timer
        2. 8.9.6.2. System.Threading.Timer
        3. 8.9.6.3. System.Windows.Forms.Timer
        4. 8.9.6.4. Choosing a timer
      7. 8.9.7. Volatile Fields
      8. 8.9.8. .NET and COM's Apartments
  13. 9. Serialization and Persistence
    1. 9.1. Automatic Serialization
      1. 9.1.1. The Serializable Attribute
      2. 9.1.2. Non-Serializable Members
        1. 9.1.2.1. Delegates and serialization
    2. 9.2. Serialization Formatters
      1. 9.2.1. The Binary Formatter
      2. 9.2.2. The SOAP Formatter
      3. 9.2.3. Generic Formatters
      4. 9.2.4. Serialization of Generic Type Parameters
    3. 9.3. Serialization Events
      1. 9.3.1. Applying the Event Attributes
      2. 9.3.2. Serialization Events and Class Hierarchies
        1. 9.3.2.1. Using the deserializing event
        2. 9.3.2.2. Using the deserialized event
      3. 9.3.3. Serialization and Versioning
      4. 9.3.4. Type-Version Tolerance
    4. 9.4. Serialization and Streams
      1. 9.4.1. Serializing Multiple Objects
    5. 9.5. Custom Serialization
      1. 9.5.1. The ISerializable Interface
      2. 9.5.2. Implementing ISerializable
        1. 9.5.2.1. GenericSerializationInfo
        2. 9.5.2.2. Custom serialization and IDeserializationCallback
        3. 9.5.2.3. Custom serialization and serialization events
      3. 9.5.3. Constraining Serialization
    6. 9.6. Serialization and Class Hierarchies
      1. 9.6.1. Custom Serialization and Base Classes
      2. 9.6.2. Manual Base-Class Serialization
  14. 10. Remoting
    1. 10.1. Application Domains
      1. 10.1.1. App Domains Versus Physical Processes
      2. 10.1.2. App Domains and the .NET Platform
        1. 10.1.2.1. App domains and threads
      3. 10.1.3. App Domains and Remoting
      4. 10.1.4. The AppDomain Class
        1. 10.1.4.1. The default app domain
        2. 10.1.4.2. Creating objects in app domains
        3. 10.1.4.3. Creating a new app domain
        4. 10.1.4.4. Unwrapping remote objects
      5. 10.1.5. The Host App Domain
    2. 10.2. Remote Object Types
      1. 10.2.1. Marshaling by Value
      2. 10.2.2. Marshaling by Reference
    3. 10.3. Marshaling-by-Reference Activation Modes
      1. 10.3.1. Client-Activated Object
      2. 10.3.2. Server-Activated Single Call
        1. 10.3.2.1. Benefits of single-call objects
        2. 10.3.2.2. Designing a single-call object
        3. 10.3.2.3. Applying the single-call mode
      3. 10.3.3. Server-Activated Singleton
        1. 10.3.3.1. Using singleton objects
        2. 10.3.3.2. Singleton object lifecycle
      4. 10.3.4. Activation Modes and Synchronization
        1. 10.3.4.1. Client-activated objects and synchronization
        2. 10.3.4.2. Single-call objects and synchronization
        3. 10.3.4.3. Singleton objects and synchronization
    4. 10.4. The .NET Remoting Architecture
      1. 10.4.1. Client-Side Processing
      2. 10.4.2. Server-Side Processing
      3. 10.4.3. Formatters
      4. 10.4.4. Transport Channels
      5. 10.4.5. Object Locations and Identity
      6. 10.4.6. Error Handling
    5. 10.5. Building a Distributed Application
      1. 10.5.1. Programmatic Channel Registration
        1. 10.5.1.1. Host channel registration
        2. 10.5.1.2. Channels and formats
      2. 10.5.2. Programmatic Type Registration
        1. 10.5.2.1. Host type registration
        2. 10.5.2.2. Client-side type registration
      3. 10.5.3. Programmatic Configuration Example
      4. 10.5.4. Administrative Configuration
        1. 10.5.4.1. Visual Studio 2005 and configuration files
      5. 10.5.5. Administrative Channel Registration
        1. 10.5.5.1. Host channels registration
        2. 10.5.5.2. Channels and formats
      6. 10.5.6. Administrative Type Registration
        1. 10.5.6.1. Host type registration
        2. 10.5.6.2. Client-side type registration
      7. 10.5.7. Administrative Configuration Example
      8. 10.5.8. Creating Remote Objects
        1. 10.5.8.1. RemotingServices.Connect()
        2. 10.5.8.2. Activator.GetObject()
        3. 10.5.8.3. Activator.CreateInstance()
        4. 10.5.8.4. Creating remote generic objects
      9. 10.5.9. Remote Callbacks
        1. 10.5.9.1. Registering callback channels
        2. 10.5.9.2. Remote callbacks and type filtering
        3. 10.5.9.3. Remote callbacks and metadata
        4. 10.5.9.4. Remote callbacks and error handling
        5. 10.5.9.5. Remote callback example
      10. 10.5.10. Separating the Server Code from its Metadata
      11. 10.5.11. Providing a Host as a System Service
        1. 10.5.11.1. Hosting with IIS
    6. 10.6. Leasing and Sponsorship
      1. 10.6.1. Lease Properties
        1. 10.6.1.1. Lease manager properties
        2. 10.6.1.2. Configuring global default properties
      2. 10.6.2. Configuring a Lease
      3. 10.6.3. Renewing a Lease
      4. 10.6.4. Providing a Sponsor
        1. 10.6.4.1. Sponsors and remoting
        2. 10.6.4.2. Client and leases
      5. 10.6.5. Leasing and Remote Activation Modes
        1. 10.6.5.1. Leasing a singleton object
        2. 10.6.5.2. Leasing a client-activated object
      6. 10.6.6. Sponsorship Management
    7. 10.7. .NET and Location Transparency
  15. 11. Context and Interception
    1. 11.1. .NET Component Services
      1. 11.1.1. Contexts and Object Types
      2. 11.1.2. Component Services Types
    2. 11.2. The .NET Context
      1. 11.2.1. Assigning Objects to Contexts
      2. 11.2.2. The Call Interception Architecture
        1. 11.2.2.1. Cross-context sinks
        2. 11.2.2.2. Message sink types
      3. 11.2.3. Same-Context Calls
      4. 11.2.4. Context-Bound Objects and Remoting
    3. 11.3. Custom Component Services
      1. 11.3.1. Building a Custom Context Attribute
      2. 11.3.2. Installing a Custom Message Sink
        1. 11.3.2.1. Providing a server context sink
        2. 11.3.2.2. Providing a client context sink
        3. 11.3.2.3. Providing an envoy sink
        4. 11.3.2.4. Providing an object sink
        5. 11.3.2.5. Processing messages
      3. 11.3.3. The Logbook Service
        1. 11.3.3.1. Using the logbook
        2. 11.3.3.2. The logbook service architecture
        3. 11.3.3.3. Implementing the logbook
      4. 11.3.4. The Transaction Management Service
        1. 11.3.4.1. Transaction flow management
        2. 11.3.4.2. Declarative transaction support
  16. 12. Security
    1. 12.1. The .NET Security Architecture
      1. 12.1.1. Permissions
      2. 12.1.2. Permission Sets
      3. 12.1.3. Security Evidence
        1. 12.1.3.1. The All Code evidence
        2. 12.1.3.2. The Application Directory evidence
        3. 12.1.3.3. The GAC evidence
        4. 12.1.3.4. The Site evidence
        5. 12.1.3.5. The URL evidence
        6. 12.1.3.6. The Zone evidence
        7. 12.1.3.7. The Strong Name evidence
        8. 12.1.3.8. The Hash evidence
        9. 12.1.3.9. The Publisher evidence
        10. 12.1.3.10. Selecting a security evidence
      4. 12.1.4. Code Groups and Security Policies
        1. 12.1.4.1. Combining policies
        2. 12.1.4.2. Policy levels
      5. 12.1.5. How It All Works Together
    2. 12.2. Configuring Permissions
      1. 12.2.1. .NET Default Configuration
        1. 12.2.1.1. The Enterprise and User policies
        2. 12.2.1.2. The Machine policy
      2. 12.2.2. Custom Permission Sets
      3. 12.2.3. Custom Code Groups
        1. 12.2.3.1. Non-administrative permissions
      4. 12.2.4. Administrating Security for ClickOnce Applications
        1. 12.2.4.1. ClickOnce versioning and security
        2. 12.2.4.2. Trusting ClickOnce application publishers
      5. 12.2.5. Custom Security Policies
        1. 12.2.5.1. Custom server-side policy
        2. 12.2.5.2. Custom client-side policy
      6. 12.2.6. Security Administration Utilities
        1. 12.2.6.1. Resetting policies
        2. 12.2.6.2. Managing policy files
        3. 12.2.6.3. Adjusting security
        4. 12.2.6.4. Evaluating an assembly
        5. 12.2.6.5. Trusting an assembly
        6. 12.2.6.6. Exporting security policies
      7. 12.2.7. Security Infrastructure Benefits
    3. 12.3. Programmatic Security
      1. 12.3.1. The Permission Classes
        1. 12.3.1.1. Permission demand
        2. 12.3.1.2. Permission interactions
      2. 12.3.2. Stack-Walk Modifiers
        1. 12.3.2.1. Denying and permitting permissions
        2. 12.3.2.2. Asserting permissions
        3. 12.3.2.3. Asserting unmanaged code access permission
      3. 12.3.3. Permission Attributes
        1. 12.3.3.1. Choice actions
        2. 12.3.3.2. Link-time demands
        3. 12.3.3.3. Inheritance demand
      4. 12.3.4. Permission Set Classes
        1. 12.3.4.1. Permission set collection
      5. 12.3.5. Permission Set Attributes
      6. 12.3.6. Assembly-Wide Permissions
    4. 12.4. Visual Studio 2005 and Security
      1. 12.4.1. ClickOnce Permissions
      2. 12.4.2. Calculating Required Permissions
      3. 12.4.3. Partial-Trust Debugging
      4. 12.4.4. Visual Basic 2005 and Security
    5. 12.5. Principal-Based Security
      1. 12.5.1. Declarative Role-Based Security
        1. 12.5.1.1. Enabling role-based security
        2. 12.5.1.2. Role-based security and authentication
      2. 12.5.2. Programmatic Role-Based Security
        1. 12.5.2.1. Principal and identity
        2. 12.5.2.2. Verifying role membership
      3. 12.5.3. Windows Security Principal
      4. 12.5.4. Custom Security Principal
    6. 12.6. Addressing Other Security Issues
      1. 12.6.1. Link-Time Demand and Reflection
      2. 12.6.2. Link-Time Demand and Inheritance
      3. 12.6.3. Strongly Named Assemblies and Full Trust
      4. 12.6.4. Unsafe Code
      5. 12.6.5. Security and Remote Calls
      6. 12.6.6. Serialization
      7. 12.6.7. Transactions
  17. A. Interface-Based Web Services
    1. .NET Web Services Support
    2. Problem Statement
    3. Solution
      1. Service-Side Steps
      2. Client-Side Steps
  18. B. Unifying Windows Forms and ASP.NET Security
    1. ASP.NET Security Infrastructure
      1. ASP.NET Custom Authentication and Authorization
    2. Solution Architecture
      1. Implementing IPrincipal
      2. The LoginControl Class
        1. Providing input to LoginControl
        2. Authenticating the user
    3. The AspNetLoginControl
      1. Implementing IUserManager
      2. AspNetLoginControl and Code Access Security
    4. The UserManager Web Service
    5. The WSLoginControl
      1. WSLoginControl and Code Access Security
    6. The Sample Application
      1. The LoginDialog Class
  19. C. Reflection and Attributes
    1. System.Type
    2. Attributes
      1. Using Attributes
      2. Kinds of Attributes
    3. Implementing Custom Attributes
      1. Reflecting Custom Attributes
    4. Generics and Reflection
      1. Attributes and Generics
  20. D. Generics
    1. Generics Problem Statement
    2. What Are Generics?
    3. Generics Implementation
    4. Applying Generics
      1. Multiple Generic Types
    5. Generic Constraints
      1. Derivation Constraint
      2. Constructor Constraint
      3. Class/Struct Type Constraint
  21. E. C# Coding Standard
    1. Naming Conventions and Styles
    2. Coding Practices
    3. Project Settings and Project Structure
    4. Framework-Specific Guidelines
      1. Multithreading
      2. Serialization
      3. Remoting
      4. Security
  22. Colophon
  23. Copyright