Pro C# 8 with .NET Core 3: Foundational Principles and Practices in Programming

This document was uploaded by one of our users. The uploader already confirmed that they had the permission to publish it. If you are author/publisher or own the copyright of this documents, please report to us by using this DMCA report form.

Simply click on the Download Book button.

Yes, Book downloads on Ebookily are 100% Free.

Sometimes the book is free on Amazon As well, so go ahead and hit "Search on Amazon"

This essential classic provides a comprehensive foundation in the C# programming language and the frameworks it lives in. Now in its 9th edition, you will find the latest C# 8 and .NET Core features, along with new chapters on Microsoft’s lightweight, cross-platform framework, .NET Core 3.1. Coverage of ASP.NET Core, Entity Framework Core, and more, sits alongside the latest updates to .NET Core, including Windows Presentation Foundation (WPF). Not only does this book cover all of the latest features in C# 8, but all chapters and code samples have been rewritten for this latest release. Dive in and discover why this book has been a favorite of C# developers worldwide for more than 15 years. Gain a solid foundation in object-oriented development techniques, attributes and reflection, generics and collections, and numerous advanced topics not found in other texts (such as CIL opcodes and emitting dynamic assemblies). With the help of Pro C# 8 with .NET Core 3 gain the confidence to put C# into practice and explore the .NET Core universe on your own terms. What You Will Learn Discover the bells and whistles of C# 8 features and updates to previous features Hit the ground running with ASP.NET Core web applications and web services, and Entity Framework Core Work with the latest version of Windows Presentation Foundation, now a part of .NET Core Understand the philosophy behind .NET and the cross-platform alternative, .NET Core Develop applications with C# and modern frameworks for services, web, and smart client applications Who This Book Is For Developers who are interested in .NET programming and the C# language “Amazing! Provides easy-to-follow explanations and examples. I remember reading the first version of this book; this is a 'must-have' for your collection if you are learning .NET Core!” – Rick McGuire, Senior Application Development Manager, Microsoft “Phil is a journeyman programmer who brings years of experience and a passion for teaching to make this fully revised and modernized ‘classic’ a ‘must-have’. Any developer who wants full-spectrum, up-to-date coverage of both the C# language and how to use it with .NET Core and ASP.NET Core should get this book.” – Brian A. Randell, Partner, MCW Technologies and Microsoft MVP

Author(s): Andrew Troelsen, Phil Japikse
Edition: 9
Publisher: Apress
Year: 2020

Language: English
Pages: 1223
Tags: C#, .Net, .Net Core

Table of Contents
About the Authors
About the Technical Reviewer
Acknowledgments
Introduction
Part I: Introducing C# and .NET Core
Chapter 1: Introducing .NET Core
Some Key Benefits of the .NET Core Platform
The .NET Core Support Lifecycle
Introducing the Building Blocks of the .NET Core Platform (CoreCLR, CoreFX, CTS, and CLS)
The Role of the Base Class Libraries
The Role of .NET Standard
What C# Brings to the Table
Major Features in Prior Releases
New Features in C# 8
Managed vs. Unmanaged Code
Additional .NET Core Aware Programming Languages
An Overview of .NET Assemblies
The Role of the Common Intermediate Language
Benefits of CIL
Compiling CIL to Platform-Specific Instructions
Precompiling CIL to Platform-Specific Instructions
The Role of .NET Core Type Metadata
The Role of the Assembly Manifest
Understanding the Common Type System
CTS Class Types
CTS Interface Types
CTS Structure Types
CTS Enumeration Types
CTS Delegate Types
CTS Type Members
Intrinsic CTS Data Types
Understanding the Common Language Specification
Ensuring CLS Compliance
Understanding the CoreCLR and CoreFX
The Assembly/Namespace/Type Distinction
Accessing a Namespace Programmatically
Referencing External Assemblies
Exploring an Assembly Using ildasm.exe
Summary
Chapter 2: Building C# Applications
Installing .NET Core
Confirm the .NET Core Install
Building .NET Core Applications with Visual Studio
Installing Visual Studio 2019
Taking Visual Studio 2019 for a Test-Drive
The New Project Dialog Box and C# Code Editor
Changing the Target .NET Core Framework
Using C# 8 Features
Running and Debugging Your Project
Solution Explorer
The Visual Class Designer
The .NET Framework Documentation
Building .NET Core Applications on a Non-Windows OS
Summary
Part II: Core C# Programming
Chapter 3: Core C# Programming Constructs, Part 1
The Anatomy of a Simple C# Program
Variations on the Main() Method (Updated 7.1)
Specifying an Application Error Code
Processing Command-Line Arguments
Specifying Command-Line Arguments with Visual Studio
An Interesting Aside: Some Additional Members of the System.Environment Class
The System.Console Class
Basic Input and Output with the Console Class
Formatting Console Output
Formatting Numerical Data
Formatting Numerical Data Beyond Console Applications
System Data Types and Corresponding C# Keywords
Variable Declaration and Initialization
The default Literal (New 7.1)
Intrinsic Data Types and the new Operator
The Data Type Class Hierarchy
Members of Numerical Data Types
Members of System.Boolean
Members of System.Char
Parsing Values from String Data
Using TryParse to Parse Values from String Data
System.DateTime and System.TimeSpan
The System.Numerics Namespace
Digit Separators (New 7.0)
Binary Literals (New 7.0/7.2)
Working with String Data
Basic String Manipulation
String Concatenation
Escape Characters
String Interpolation
Defining Verbatim Strings (Updated 8)
Strings and Equality
Modifying String Comparison Behavior
Strings Are Immutable
The System.Text.StringBuilder Type
Narrowing and Widening Data Type Conversions
The checked Keyword
Setting Project-Wide Overflow Checking
The unchecked Keyword
Understanding Implicitly Typed Local Variables
Declaring Numerics Implicitly
Restrictions on Implicitly Typed Variables
Implicit Typed Data Is Strongly Typed Data
Usefulness of Implicitly Typed Local Variables
C# Iteration Constructs
The for Loop
The foreach Loop
Use of Implicit Typing Within foreach Constructs
The while and do/while Looping Constructs
A Quick Discussion About Scope
Decision Constructs and the Relational/Equality Operators
The if/else Statement
Equality and Relational Operators
if/else with Pattern Matching (New 7.0)
The Conditional Operator (Updated 7.2)
Logical Operators
The switch Statement
Switch Statement Pattern Matching (New 7.0)
Switch Expressions (New 8.0)
Summary
Chapter 4: Core C# Programming Constructs, Part 2
Understanding C# Arrays
C# Array Initialization Syntax
Implicitly Typed Local Arrays
Defining an Array of Objects
Working with Multidimensional Arrays
Arrays As Arguments or Return Values
The System.Array Base Class
Indices and Ranges (New 8.0)
Methods
Expression-Bodied Members
Local Functions (New 7.0)
Static Local Functions (New 8.0)
Method Parameters
Method Parameter Modifiers
The Default Parameter-Passing Behavior
The Default Behavior for Value Types
The Default Behavior for Reference Types
The out Modifier (Updated 7.0)
Discards (New 7.0)
The out Modifier in Constructors and Initializers (New 7.3)
The ref Modifier
The in Modifier (New 7.2)
The params Modifier
Defining Optional Parameters
Using Named Arguments (Updated 7.2)
Understanding Method Overloading
Understanding the enum Type
Controlling the Underlying Storage for an enum
Declaring enum Variables
The System.Enum Type
Dynamically Discovering an enum’s Name-Value Pairs
Understanding the Structure (aka Value Type)
Creating Structure Variables
Readonly Structs (New 7.2)
Readonly members (New 8.0)
ref Structs (New 7.2)
Disposable ref Structs (New 8.0)
Understanding Value Types and Reference Types
Value Types, Reference Types, and the Assignment Operator
Value Types Containing Reference Types
Passing Reference Types by Value
Passing Reference Types by Reference
Final Details Regarding Value Types and Reference Types
Understanding C# Nullable Types
Nullable Value Types
Nullable Reference Types (New 8.0)
Opting in for Nullable Reference Types
Nullable Reference Types in Action
Migration Considerations
The Null-Coalescing Operator
The Null-Coalescing Assignment Operator (New 8.0)
The Null Conditional Operator
Tuples (New/Updated 7.0)
Getting Started with Tuples
Inferred Variable Names (Updated 7.1)
Tuple Equality/Inequality (New 7.3)
Tuples As Method Return Values
Discards with Tuples
Tuple Pattern Matching Switch Expressions (New 8.0)
Deconstructing Tuples
Deconstructing Tuples with Positional Pattern Matching (New 8.0)
Summary
Part III: Object-Oriented Programming with C#
Chapter 5: Understanding Encapsulation
Introducing the C# Class Type
Allocating Objects with the new Keyword
Understanding Constructors
The Role of the Default Constructor
Defining Custom Constructors
Constructors As Expression-Bodied Members (New 7.0)
Constructors with out Parameters (New 7.3)
The Default Constructor Revisited
The Role of the this Keyword
Chaining Constructor Calls Using this
Observing Constructor Flow
Revisiting Optional Arguments
Understanding the static Keyword
Defining Static Field Data
Defining Static Methods
Defining Static Constructors
Defining Static Classes
Importing Static Members via the C# using Keyword
Defining the Pillars of OOP
The Role of Encapsulation
The Role of Inheritance
The Role of Polymorphism
C# Access Modifiers (Updated 7.2)
The Default Access Modifiers
Access Modifiers and Nested Types
The First Pillar: C#’s Encapsulation Services
Encapsulation Using Traditional Accessors and Mutators
Encapsulation Using Properties
Properties As Expression-Bodied Members (New 7.0)
Using Properties Within a Class Definition
Read-Only and Write-Only Properties
Mixing Private and Public Get/Set Methods on Properties
Pattern Matching with Property Patterns (New 8.0)
Revisiting the static Keyword: Defining Static Properties
Understanding Automatic Properties
Interacting with Automatic Properties
Automatic Properties and Default Values
Initialization of Automatic Properties
Understanding Object Initialization Syntax
Calling Custom Constructors with Initialization Syntax
Initializing Data with Initialization Syntax
Working with Constant Field Data
Understanding Read-Only Fields
Static Read-Only Fields
Understanding Partial Classes
Use Cases for Partial Classes?
Summary
Chapter 6: Understanding Inheritance and Polymorphism
The Basic Mechanics of Inheritance
Specifying the Parent Class of an Existing Class
Regarding Multiple Base Classes
The sealed Keyword
Revisiting Visual Studio Class Diagrams
The Second Pillar of OOP: The Details of Inheritance
Controlling Base Class Creation with the base Keyword
Keeping Family Secrets: The protected Keyword
Adding a sealed Class
Programming for Containment/Delegation
Understanding Nested Type Definitions
The Third Pillar of OOP: C#’s Polymorphic Support
The virtual and override Keywords
Overriding Virtual Members Using the Visual Studio IDE
Sealing Virtual Members
Understanding Abstract Classes
Understanding the Polymorphic Interface
Understanding Member Shadowing
Understanding Base Class/Derived Class Casting Rules
The C# as Keyword
The C# is Keyword (Updated 7.0)
Discards with the is Keyword (New 7.0)
Pattern Matching Revisited (New 7.0)
Discards with switch Statements (New 7.0)
The Super Parent Class: System.Object
Overriding System.Object.ToString()
Overriding System.Object.Equals()
Overriding System.Object.GetHashCode()
Testing Your Modified Person Class
The Static Members of System.Object
Summary
Chapter 7: Understanding Structured Exception Handling
Ode to Errors, Bugs, and Exceptions
The Role of .NET Exception Handling
The Building Blocks of .NET Exception Handling
The System.Exception Base Class
The Simplest Possible Example
Throwing a General Exception
Catching Exceptions
Throw As Expression (New 7.0)
Configuring the State of an Exception
The TargetSite Property
The StackTrace Property
The HelpLink Property
The Data Property
System-Level Exceptions (System.SystemException)
Application-Level Exceptions (System.ApplicationException)
Building Custom Exceptions, Take 1
Building Custom Exceptions, Take 2
Building Custom Exceptions, Take 3
Processing Multiple Exceptions
General catch Statements
Rethrowing Exceptions
Inner Exceptions
The finally Block
Exception Filters
Debugging Unhandled Exceptions Using Visual Studio
Summary
Chapter 8: Working with Interfaces
Understanding Interface Types
Interface Types vs. Abstract Base Classes
Defining Custom Interfaces
Implementing an Interface
Invoking Interface Members at the Object Level
Obtaining Interface References: The as Keyword
Obtaining Interface References: The is Keyword (Updated 7.0)
Default Implementations (New 8.0)
Static Constructors and Members (New 8.0)
Interfaces As Parameters
Interfaces As Return Values
Arrays of Interface Types
Implementing Interfaces Using Visual Studio
Explicit Interface Implementation
Designing Interface Hierarchies
Interface Hierarchies with Default Implementations (New 8.0)
Multiple Inheritance with Interface Types
The IEnumerable and IEnumerator Interfaces
Building Iterator Methods with the yield Keyword
Guard Clauses with Local Functions (New 7.0)
Building a Named Iterator
The ICloneable Interface
A More Elaborate Cloning Example
The IComparable Interface
Specifying Multiple Sort Orders with IComparer
Custom Properties and Custom Sort Types
Summary
Chapter 9: Understanding Object Lifetime
Classes, Objects, and References
The Basics of Object Lifetime
The CIL of new
Setting Object References to null
Determining If an Object Is Live
Understanding Object Generations
Ephemeral Generations and Segments
Garbage Collection Types
Background Garbage Collection
The System.GC Type
Forcing a Garbage Collection
Building Finalizable Objects
Overriding System.Object.Finalize()
Detailing the Finalization Process
Building Disposable Objects
Reusing the C# using Keyword
Using Declarations (New 8.0)
Building Finalizable and Disposable Types
A Formalized Disposal Pattern
Understanding Lazy Object Instantiation
Customizing the Creation of the Lazy Data
Summary
Part IV: Advanced C# Programming
Chapter 10: Collections and Generics
The Motivation for Collection Classes
The System.Collections Namespace
An Illustrative Example: Working with the ArrayList
A Survey of System.Collections.Specialized Namespace
The Problems of Nongeneric Collections
The Issue of Performance
The Issue of Type Safety
A First Look at Generic Collections
The Role of Generic Type Parameters
Specifying Type Parameters for Generic Classes/Structures
Specifying Type Parameters for Generic Members
Specifying Type Parameters for Generic Interfaces
The System.Collections.Generic Namespace
Understanding Collection Initialization Syntax
Working with the List Class
Working with the Stack Class
Working with the Queue Class
Working with the SortedSet Class
Working with the Dictionary Class
The System.Collections.ObjectModel Namespace
Working with ObservableCollection
Creating Custom Generic Methods
Inference of Type Parameters
Creating Custom Generic Structures and Classes
Default Value Expressions with Generics
Default Literal Expressions (New 7.1)
Pattern Matching with Generics (New 7.1)
Constraining Type Parameters
Examples Using the where Keyword
The Lack of Operator Constraints
Summary
Chapter 11: Advanced C# Language Features
Understanding Indexer Methods
Indexing Data Using String Values
Overloading Indexer Methods
Indexers with Multiple Dimensions
Indexer Definitions on Interface Types
Understanding Operator Overloading
Overloading Binary Operators
And What of the += and –= Operators?
Overloading Unary Operators
Overloading Equality Operators
Overloading Comparison Operators
Final Thoughts Regarding Operator Overloading
Understanding Custom Type Conversions
Recall: Numerical Conversions
Recall: Conversions Among Related Class Types
Creating Custom Conversion Routines
Additional Explicit Conversions for the Square Type
Defining Implicit Conversion Routines
Understanding Extension Methods
Defining Extension Methods
Invoking Extension Methods
Importing Extension Methods
Extending Types Implementing Specific Interfaces
Understanding Anonymous Types
Defining an Anonymous Type
The Internal Representation of Anonymous Types
The Implementation of ToString() and GetHashCode()
The Semantics of Equality for Anonymous Types
Anonymous Types Containing Anonymous Types
Working with Pointer Types
The unsafe Keyword
Working with the * and & Operators
An Unsafe (and Safe) Swap Function
Field Access via Pointers (the -> Operator)
The stackalloc Keyword
Pinning a Type via the fixed Keyword
The sizeof Keyword
Summary
Chapter 12: Delegates, Events, and Lambda Expressions
Understanding the Delegate Type
Defining a Delegate Type in C#
The System.MulticastDelegate and System.Delegate Base Classes
The Simplest Possible Delegate Example
Investigating a Delegate Object
Sending Object State Notifications Using Delegates
Enabling Multicasting
Removing Targets from a Delegate’s Invocation List
Method Group Conversion Syntax
Understanding Generic Delegates
The Generic Action<> and Func<> Delegates
Understanding C# Events
The C# event Keyword
Events Under the Hood
Listening to Incoming Events
Simplifying Event Registration Using Visual Studio
Creating Custom Event Arguments
The Generic EventHandler Delegate
Understanding C# Anonymous Methods
Accessing Local Variables
Understanding Lambda Expressions
Dissecting a Lambda Expression
Processing Arguments Within Multiple Statements
Lambda Expressions with Multiple (or Zero) Parameters
Retrofitting the CarEvents Example Using Lambda Expressions
Lambdas and Expression-Bodied Members (Updated 7.0)
Summary
Chapter 13: LINQ to Objects
LINQ-Specific Programming Constructs
Implicit Typing of Local Variables
Object and Collection Initialization Syntax
Lambda Expressions
Extension Methods
Anonymous Types
Understanding the Role of LINQ
LINQ Expressions Are Strongly Typed
The Core LINQ Assemblies
Applying LINQ Queries to Primitive Arrays
Once Again, Using Extension Methods
Once Again, Without LINQ
Reflecting Over a LINQ Result Set
LINQ and Implicitly Typed Local Variables
LINQ and Extension Methods
The Role of Deferred Execution
The Role of Immediate Execution
Returning the Result of a LINQ Query
Returning LINQ Results via Immediate Execution
Applying LINQ Queries to Collection Objects
Accessing Contained Subobjects
Applying LINQ Queries to Nongeneric Collections
Filtering Data Using OfType()
Investigating the C# LINQ Query Operators
Basic Selection Syntax
Obtaining Subsets of Data
Projecting New Data Types
Projecting to Different Data Types
Obtaining Counts Using Enumerable
Reversing Result Sets
Sorting Expressions
LINQ As a Better Venn Diagramming Tool
Removing Duplicates
LINQ Aggregation Operations
The Internal Representation of LINQ Query Statements
Building Query Expressions with Query Operators (Revisited)
Building Query Expressions Using the Enumerable Type and Lambda Expressions
Building Query Expressions Using the Enumerable Type and Anonymous Methods
Building Query Expressions Using the Enumerable Type and Raw Delegates
Summary
Chapter 14: Processes, AppDomains, and Load Contexts
The Role of a Windows Process
The Role of Threads
Interacting with Processes Using .NET Core
Enumerating Running Processes
Investigating a Specific Process
Investigating a Process’s Thread Set
Investigating a Process’s Module Set
Starting and Stopping Processes Programmatically
Controlling Process Startup Using the ProcessStartInfo Class
Leveraging OS Verbs with ProcessStartInfo
Understanding .NET Application Domains
The System.AppDomain Class
Interacting with the Default Application Domain
Enumerating Loaded Assemblies
Assembly Isolation with Application Load Contexts
Summarizing Processes, AppDomains, and Load Contexts
Summary
Chapter 15: Multithreaded, Parallel, and Async Programming
The Process/AppDomain/Context/Thread Relationship
The Problem of Concurrency
The Role of Thread Synchronization
The System.Threading Namespace
The System.Threading.Thread Class
Obtaining Statistics About the Current Thread of Execution
The Name Property
The Priority Property
Manually Creating Secondary Threads
Working with the ThreadStart Delegate
Working with the ParameterizedThreadStart Delegate
The AutoResetEvent Class
Foreground Threads and Background Threads
The Issue of Concurrency
Synchronization Using the C# lock Keyword
Synchronization Using the System.Threading.Monitor Type
Synchronization Using the System.Threading.Interlocked Type
Programming with Timer Callbacks
Using a Stand-Alone Discard
Understanding the ThreadPool
Parallel Programming Using the Task Parallel Library (TPL)
The System.Threading.Tasks Namespace
The Role of the Parallel Class
Data Parallelism with the Parallel Class
Accessing UI Elements on Secondary Threads
The Task Class
Handling Cancellation Request
Task Parallelism Using the Parallel Class
Parallel LINQ Queries (PLINQ)
Opting in to a PLINQ Query
Cancelling a PLINQ Query
Async Calls with the async/await (Updated 7.0/7.1)
A First Look at the C# async and await Keywords
Naming Conventions for Asynchronous Methods
Async Methods Returning Void
Async Methods with Multiple Awaits
Calling Async Methods from Non-async Methods
Await in catch and finally Blocks
Generalized Async Return Types (New 7.0)
Local Functions (New 7.0)
Cancelling Async/Await Operations
Asynchronous Streams (New 8.0)
Wrapping Up async and await
Summary
Part V: Programming with .NET Core Assemblies
Chapter 16: Building and Configuring Class Libraries
Defining Custom Namespaces
Resolving Name Clashes with Fully Qualified Names
Resolving Name Clashes with Aliases
Creating Nested Namespaces
Change the Root Namespace of Visual Studio
The Role of .NET Core Assemblies
Assemblies Promote Code Reuse
Assemblies Establish a Type Boundary
Assemblies Are Versionable Units
Assemblies Are Self-Describing
Understanding the Format of a .NET Core Assembly
Installing the C++ Profiling Tools
The Operating System (Windows) File Header
The CLR File Header
CIL Code, Type Metadata, and the Assembly Manifest
Optional Assembly Resources
Class Libraries vs. Console Applications
.NET Standard vs. .NET Core Class Libraries
Configuring Applications
Building and Consuming a .NET Core Class Library
Exploring the Manifest
Exploring the CIL
Exploring the Type Metadata
Building a C# Client Application
Building a Visual Basic Client Application
Cross-Language Inheritance in Action
Exposing internal Types to Other Assemblies
Using an Assembly Attribute
Using the Project File
NuGet and .NET Core
Packaging Assemblies with NuGet
Referencing NuGet Packages
How .NET Core Locates Assemblies
Summary
Chapter 17: Type Reflection, Late Binding, and Attribute-Based Programming
The Necessity of Type Metadata
Viewing (Partial) Metadata for the EngineState Enumeration
Viewing (Partial) Metadata for the Car Type
Examining a TypeRef
Documenting the Defining Assembly
Documenting Referenced Assemblies
Documenting String Literals
Understanding Reflection
The System.Type Class
Obtaining a Type Reference Using System.Object.GetType()
Obtaining a Type Reference Using typeof()
Obtaining a Type Reference Using System.Type.GetType()
Building a Custom Metadata Viewer
Reflecting on Methods
Reflecting on Fields and Properties
Reflecting on Implemented Interfaces
Displaying Various Odds and Ends
Implementing Main()
Reflecting on Static Types
Reflecting on Generic Types
Reflecting on Method Parameters and Return Values
Dynamically Loading Assemblies
Reflecting on Framework Assemblies
Understanding Late Binding
The System.Activator Class
Invoking Methods with No Parameters
Invoking Methods with Parametersng ng
Understanding the Role of .NET Attributes
Attribute Consumers
Applying Attributes in C#
C# Attribute Shorthand Notation
Specifying Constructor Parameters for Attributes
The Obsolete Attribute in Action
Building Custom Attributes
Applying Custom Attributes
Named Property Syntax
Restricting Attribute Usage
Assembly-Level Attributes
Using the Project File for Assembly Attributes
Reflecting on Attributes Using Early Binding
Reflecting on Attributes Using Late Binding
Putting Reflection, Late Binding, and Custom Attributes in Perspective
Building an Extendable Application
Building the Multiproject ExtendableApp Solution
Building CommonSnappableTypes.dll
Adding Projects to the Solution
Building the C# Snap-In
Building the Visual Basic Snap-In
Create the Console Application
Setting Project Build Dependencies
Adding PostBuild Events
Adding the Code for the ExtendableApp
Summary
Chapter 18: Dynamic Types and the Dynamic Language Runtime
The Role of the C# dynamic Keyword
Calling Members on Dynamically Declared Data
The Scope of the dynamic Keyword
Limitations of the dynamic Keyword
Practical Uses of the dynamic Keyword
The Role of the Dynamic Language Runtime
The Role of Expression Trees
Dynamic Runtime Lookup of Expression Trees
Simplifying Late-Bound Calls Using Dynamic Types
Leveraging the dynamic Keyword to Pass Arguments
Simplifying COM Interoperability Using Dynamic Data (Windows Only)
The Role of Primary Interop Assemblies
Embedding Interop Metadata
Common COM Interop Pain Points
COM Interop Using C# Dynamic Data
Summary
Chapter 19: Understanding CIL and the Role of Dynamic Assemblies
Motivations for Learning the Grammar of CIL
Examining CIL Directives, Attributes, and Opcodes
The Role of CIL Directives
The Role of CIL Attributes
The Role of CIL Opcodes
The CIL Opcode/CIL Mnemonic Distinction
Pushing and Popping: The Stack-Based Nature of CIL
Understanding Round-Trip Engineering
The Role of CIL Code Labels
Interacting with CIL: Modifying an *.il File
Compiling CIL Code
Understanding CIL Directives and Attributes
Specifying Externally Referenced Assemblies in CIL
Defining the Current Assembly in CIL
Defining Namespaces in CIL
Defining Class Types in CIL
Defining and Implementing Interfaces in CIL
Defining Structures in CIL
Defining Enums in CIL
Defining Generics in CIL
Compiling the CILTypes.il File
.NET Base Class Library, C#, and CIL Data Type Mappings
Defining Type Members in CIL
Defining Field Data in CIL
Defining Type Constructors in CIL
Defining Properties in CIL
Defining Member Parameters
Examining CIL Opcodes
The .maxstack Directive
Declaring Local Variables in CIL
Mapping Parameters to Local Variables in CIL
The Hidden this Reference
Representing Iteration Constructs in CIL
The Final Word on CIL
Understanding Dynamic Assemblies
Exploring the System.Reflection.Emit Namespace
The Role of the System.Reflection.Emit.ILGenerator
Emitting a Dynamic Assembly
Emitting the Assembly and Module Set
The Role of the ModuleBuilder Type
Emitting the HelloClass Type and the String Member Variable
Emitting the Constructors
Emitting the SayHello() Method
Using the Dynamically Generated Assembly
Summary
Part VI: File and Data Handling
Chapter 20: File I/O and Object Serialization
Exploring the System.IO Namespace
The Directory(Info) and File(Info) Types
The Abstract FileSystemInfo Base Class
Working with the DirectoryInfo Type
Enumerating Files with the DirectoryInfo Type
Creating Subdirectories with the DirectoryInfo Type
Working with the Directory Type
Working with the DriveInfo Class Type
Working with the FileInfo Class
The FileInfo.Create() Method
The FileInfo.Open() Method
The FileInfo.OpenRead() and FileInfo.OpenWrite() Methods
The FileInfo.OpenText() Method
The FileInfo.CreateText() and FileInfo.AppendText() Methods
Working with the File Type
Additional File-Centric Members
The Abstract Stream Class
Working with FileStreams
Working with StreamWriters and StreamReaders
Writing to a Text File
Reading from a Text File
Directly Creating StreamWriter/StreamReader Types
Working with StringWriters and StringReaders
Working with BinaryWriters and BinaryReaders
Watching Files Programmatically
Understanding Object Serialization
The Role of Object Graphs
Configuring Objects for Serialization
Defining Serializable Types
Public Fields, Private Fields, and Public Properties
Choosing a Serialization Formatter
The IFormatter and IRemotingFormatter Interfaces
Type Fidelity Among the Formatters
Exploring the BinaryFormatter
Serializing Objects
Deserializing Objects
Serializing Objects Using the XmlSerializer
Controlling the Generated XML Data
Serializing Collections of Objects
Customizing the Binary Serialization Process
A Deeper Look at Object Serialization
Customizing Serialization Using ISerializable
Customizing Serialization Using Attributes
Summary
Chapter 21: Data Access with ADO.NET
ADO.NET vs. ADO
Understanding ADO.NET Data Providers
ADO.NET Data Providers
The Types of the System.Data Namespace
The Role of the IDbConnection Interface
The Role of the IDbTransaction Interface
The Role of the IDbCommand Interface
The Role of the IDbDataParameter and IDataParameter Interfaces
The Role of the IDbDataAdapter and IDataAdapter Interfaces
The Role of the IDataReader and IDataRecord Interfaces
Abstracting Data Providers Using Interfaces
Setting Up SQL Server and Azure Data Studio
Installing Docker
Pulling the Image and Running SQL Server 2019
Installing SQL Server 2019
Installing a SQL Server IDE
Connecting to SQL Server
Connecting to SQL Server in a Docker Container
Connecting to SQL Server LocalDb
Connecting to Any Other SQL Server Instance
Restoring the AutoLot Database Backup
Copying the Backup File to Your Container
Restoring the Database with SSMS
Restoring the Database with Azure Data Studio
Creating the AutoLot Database
Creating the Database
Creating the Inventory Table
Adding Test Records to the Inventory Table
Authoring the GetPetName() Stored Procedure
Creating the Customers Table
Adding Test Records to the Customers Table
Creating the Orders Table
Adding Test Records to the Orders Table
Creating the CreditRisk Table
Creating the Table Relationships
The ADO.NET Data Provider Factory Model
A Complete Data Provider Factory Example
A Potential Drawback with the Data Provider Factory Model
Diving Deeper into Connections, Commands, and DataReaders
Working with Connection Objects
Working with ConnectionStringBuilder Objects
Working with Command Objects
Working with Data Readers
Obtaining Multiple Result Sets Using a Data Reader
Working with Create, Update, and Delete Queries
Create the Car Model
Adding the InventoryDAL Class
Adding Constructors
Opening and Closing the Connection
Adding IDisposable
Adding the Selection Methods
Inserting a New Car
Create the Strongly Type InsertCar() Method
Adding the Deletion Logic
Adding the Update Logic
Working with Parameterized Command Objects
Specifying Parameters Using the DbParameter Type
Update the GetCar Method
Update the DeleteCar Method
Update the UpdateCarPetName Method
Update the InsertAuto Method
Executing a Stored Procedure
Creating a Console-Based Client Application
Understanding Database Transactions
Key Members of an ADO.NET Transaction Object
Adding a Transaction Method to InventoryDAL
Testing Your Database Transaction
Executing Bulk Copies with ADO.NET
Exploring the SqlBulkCopy Class
Creating a Custom Data Reader
Executing the Bulk Copy
Testing the Bulk Copy
Summary
Chapter 22: Introducing Entity Framework Core
Object-Relational Mappers
Understanding the Role of the Entity Framework Core
The Building Blocks of the Entity Framework
Entities
Entity Framework Data Annotations
Navigation Properties and Foreign Keys
The Fluent API
The DbContext Class
Transaction Support
The DbContextOptions Class
The DbSet Class
Query Types
The DbChangeTracker
Database Providers
Query Execution
Mixed Client-Server Evaluation
Tracking vs. NoTracking Queries
Notable EF Core Features
Concurrency Checking
Connection Resiliency
Eager Loading
Explicit Loading
Global Query Filters
Raw SQL Queries with LINQ
Parameter Passing with String Interpolation
Batching of Statements
Owned Object Types
Attach New and Existing Entities
Database Function Mapping
The EF Core Global Tool CLI Commands
The Database Commands
The Database Update Command
The DbContext Commands
The DbContext Scaffold Command
The Migrations Commands
Start the AutoLot.Dal Project
The Entities
The ApplicationDbContext
Cleaning Up the Entities
Cleaning Up the ApplicationDbContext
Add the Base Entity Class
Add the Owned Property
Add the ApplicationDbContextFactory
Update the Database
Create the Initial Migration
Apply the Migration
Remove a Migration
The Final Entity Updates
Add the Make Entity
Add a Global Query Filter on the Car Entity
Update the Required Fields
Create a Unique Index on Order
Add the View and ViewModel
Add the View
Add the ViewModel
Add the ViewModel to the ApplicationDbContext
Automatic Database and Migration Handling
Drop and Recreate the Database
Data Initialization
Create the Sample Data
Load or Delete the Sample Data
Delete the Data and Reseed the Identity Columns
Load the Data into the Database
Splitting the Entities and ViewModels from the Data Access Layer
Summary
Chapter 23: Finishing the Data Access Layer
Test-Driving the AutoLot Data Access Layer
Configure the Project
Add the TestHelper Class
Add the BaseTest Class
Add the Transacted Methods
Add the EnsureDatabase Class
Add the TestFixture Classes
Fact and Theory Methods
Reading Records
Entity State
LINQ Queries
LINQ Execution
Get All Records
Global Query Filters
Disable the Query Filters
Use the Query Filters
Retrieve a Single Record
Using First
Using Single
Filter Records
Sort Records
Load Related Data Eagerly
Load Related Data Explicitly
NoTracking Queries
SQL Queries with LINQ
Creating Records
Entity State
Adding Single Records
Adding Multiple Records at Once
Server-Side Computed Columns
Adding an Object Graph
Updating Records
Entity State
Updating Tracked Entities
Updating Non-tracked Entities
Concurrency Checking
Deleting Records
Entity State
Deleting Tracked Records
Updating Non-tracked Entities
Catching Cascade Delete Failures
Concurrency Checking
Adding Repositories for Code Reuse
Adding the IRepo Interface
Adding the BaseRepo
Implement the SaveChanges Method
Implement the Common Read Methods
The Add, Update, and Delete Methods
Entity-Specific Repo Interfaces
The Car Repository Interface
The Credit Risk Interface
The Customer Repository Interface
The Make Repository Interface
The Order Repository Interface
Implement the Entity-Specific Repositories
The Car Repository
The CreditRisk Repository
The Customer Repository
The Make Repository
The Order Repository
Summary
Part VII: Windows Client Development
Chapter 24: Introducing Windows Presentation Foundation and XAML
The Motivation Behind WPF
Unifying Diverse APIs
Providing a Separation of Concerns via XAML
Providing an Optimized Rendering Model
Simplifying Complex UI Programming
Investigating the WPF Assemblies
The Role of the Application Class
Constructing an Application Class
Enumerating the Windows Collection
The Role of the Window Class
The Role of System.Windows.Controls.ContentControl
The Role of System.Windows.Controls.Control
The Role of System.Windows.FrameworkElement
The Role of System.Windows.UIElement
The Role of System.Windows.Media.Visual
The Role of System.Windows.DependencyObject
The Role of System.Windows.Threading.DispatcherObject
Understanding the Syntax of WPF XAML
Introducing Kaxaml
XAML XML Namespaces and XAML “Keywords”
Controlling Class and Member Variable Visibility
XAML Elements, XAML Attributes, and Type Converters
Understanding XAML Property-Element Syntax
Understanding XAML Attached Properties
Understanding XAML Markup Extensions
Building WPF Applications Using Visual Studio
The WPF Project Templates
The Toolbox and XAML Designer/Editor
Setting Properties Using the Properties Window
Handling Events Using the Properties Window
Handling Events in the XAML Editor
The Document Outline Window
Enable or Disable the XAML Debugger
Examining the App.xaml File
Mapping the Window XAML Markup to C# Code
The Role of BAML
Solving the Mystery of Main()
Interacting with Application-Level Data
Handling the Closing of a Window Object
Intercepting Mouse Events
Intercepting Keyboard Events
Summary
Chapter 25: WPF Controls, Layouts, Events, and Data Binding
A Survey of the Core WPF Controls
The WPF Ink Controls
The WPF Document Controls
WPF Common Dialog Boxes
A Brief Review of the Visual Studio WPF Designer
Working with WPF Controls Using Visual Studio
Working with the Document Outline Editor
Controlling Content Layout Using Panels
Positioning Content Within Canvas Panels
Positioning Content Within WrapPanel Panels
Positioning Content Within StackPanel Panels
Positioning Content Within Grid Panels
Sizing Grid Columns and Rows
Grids with GridSplitter Types
Positioning Content Within DockPanel Panels
Enabling Scrolling for Panel Types
Configuring Panels Using the Visual Studio Designers
Building a Window’s Frame Using Nested Panels
Building the Menu System
Building Menus Visually
Building the Toolbar
Building the Status Bar
Finalizing the UI Design
Implementing the MouseEnter/MouseLeave Event Handlers
Implementing the Spell-Checking Logic
Understanding WPF Commands
The Intrinsic Command Objects
Connecting Commands to the Command Property
Connecting Commands to Arbitrary Actions
Working with the Open and Save Commands
Understanding Routed Events
The Role of Routed Bubbling Events
Continuing or Halting Bubbling
The Role of Routed Tunneling Events
A Deeper Look at WPF APIs and Controls
Working with the TabControl
Building the Ink API Tab
Designing the Toolbar
The RadioButton Control
Add the Save, Load, and Delete Buttons
Add the InkCanvas Control
Preview the Window
Handling Events for the Ink API Tab
Add Controls to the Toolbox
The InkCanvas Control
The ComboBox Control
Saving, Loading, and Clearing InkCanvas Data
Introducing the WPF Data-Binding Model
Building the Data Binding Tab
Establishing Data Bindings
The DataContext Property
Formatting the Bound Data
Data Conversion Using IValueConverter
Establishing Data Bindings in Code
Building the DataGrid Tab
Understanding the Role of Dependency Properties
Examining an Existing Dependency Property
Important Notes Regarding CLR Property Wrappers
Building a Custom Dependency Property
Adding a Data Validation Routine
Responding to the Property Change
Summary
Chapter 26: WPF Graphics Rendering Services
Understanding WPF’s Graphical Rendering Services
WPF Graphical Rendering Options
Rendering Graphical Data Using Shapes
Adding Rectangles, Ellipses, and Lines to a Canvas
Removing Rectangles, Ellipses, and Lines from a Canvas
Working with Polylines and Polygons
Working with Paths
The Path Modeling “Mini-Language”
WPF Brushes and Pens
Configuring Brushes Using Visual Studio
Configuring Brushes in Code
Configuring Pens
Applying Graphical Transformations
A First Look at Transformations
Transforming Your Canvas Data
Working with the Visual Studio Transform Editor
Building the Initial Layout
Applying Transformations at Design Time
Transforming the Canvas in Code
Rendering Graphical Data Using Drawings and Geometries
Building a DrawingBrush Using Geometries
Painting with the DrawingBrush
Containing Drawing Types in a DrawingImage
Working with Vector Images
Converting a Sample Vector Graphic File into XAML
Importing the Graphical Data into a WPF Project
Interacting with the Sign
Rendering Graphical Data Using the Visual Layer
The Visual Base Class and Derived Child Classes
A First Look at Using the DrawingVisual Class
Rendering Visual Data to a Custom Layout Manager
Responding to Hit-Test Operations
Summary
Chapter 27: WPF Resources, Animations, Styles, and Templates
Understanding the WPF Resource System
Working with Binary Resources
Including Loose Resource Files in a Project
Configuring the Loose Resources
Programmatically Loading an Image
Embedding Application Resources
Working with Object (Logical) Resources
The Role of the Resources Property
Defining Window-Wide Resources
The {StaticResource} Markup Extension
The {DynamicResource} Markup Extension
Application-Level Resources
Defining Merged Resource Dictionaries
Defining a Resource-Only Assembly
Understanding WPF’s Animation Services
The Role of the Animation Class Types
The To, From, and By Properties
The Role of the Timeline Base Class
Authoring an Animation in C# Code
Controlling the Pace of an Animation
Reversing and Looping an Animation
Authoring Animations in XAML
The Role of Storyboards
The Role of Event Triggers
Animation Using Discrete Key Frames
Understanding the Role of WPF Styles
Defining and Applying a Style
Overriding Style Settings
The Effect of TargetType on Styles
Subclassing Existing Styles
Defining Styles with Triggers
Defining Styles with Multiple Triggers
Animated Styles
Assigning Styles Programmatically
Logical Trees, Visual Trees, and Default Templates
Programmatically Inspecting a Logical Tree
Programmatically Inspecting a Visual Tree
Programmatically Inspecting a Control’s Default Template
Building a Control Template with the Trigger Framework
Templates As Resources
Incorporating Visual Cues Using Triggers
The Role of the {TemplateBinding} Markup Extension
The Role of ContentPresenter
Incorporating Templates into Styles
Summary
Chapter 28: WPF Notifications, Validations, Commands, and MVVM
Introducing Model-View-ViewModel
The Model
The View
The View Model
Anemic Models or Anemic View Models
The WPF Binding Notification System
Observable Models and Collections
Adding Bindings and Data
Programmatically Changing the Vehicle Data
Observable Models
Using nameof
Observable Collections
Using the ObservableCollections Class
Implementing a Dirty Flag
Updating the Source Through UI Interaction
Wrapping Up Notifications and Observables
WPF Validations
Updating the Sample for the Validation Examples
The Validation Class
Validation Options
Notify on Exceptions
IDataErrorInfo
INotifyDataErrorInfo
Implement the Supporting Code
Use INotifyDataErrorInfo for Validations
Combine IDataErrorInfo with INotifyDataErrorInfo for Validations
Show All Errors
Move the Support Code to a Base Class
Leverage Data Annotations with WPF
Add Data Annotations to the Model
Check for Data Annotation–Based Validation Errors
Customizing the ErrorTemplate
Wrapping Up Validations
Creating Custom Commands
Implementing the ICommand Interface
Adding the ChangeColorCommand
Attaching the Command to the CommandManager
Updating MainWindow.xaml.cs
Updating MainWindow.xaml
Testing the Application
Creating the CommandBase Class
Adding the AddCarCommand Class
Updating MainWindow.xaml.cs
Updating MainWindow.xaml
Updating ChangeColorCommand
RelayCommands
Creating the Base RelayCommand
Creating RelayCommand
Updating MainWindow.xaml.cs
Adding and Implementing the Delete Car Button
Wrapping Up Commands
Migrate Code and Data to a View Model
Moving the MainWindow.xaml.cs Code
Updating the MainWindow Code and Markup
Updating the Control Markup
Wrapping Up View Models
Updating AutoLot.Dal for MVVM
Summary
Part VIII: ASP.NET Core
Chapter 29: Introducing ASP.NET Core
A Quick Look Back
Introducing the MVC Pattern
The Model
The View
The Controller
ASP.NET Core and the MVC Pattern
ASP.NET Core and .NET Core
One Framework, Many Uses
ASP.NET Core Features from MVC/WebAPI
Convention over Configuration
Naming Conventions
Directory Structure
The Controllers Folder
The Views Folder
The Shared Folder
The wwwroot Folder (New in ASP. NET Core)
Controllers and Actions
The Controller Class
The ControllerBase Class
Actions
Model Binding
Implicit vs. Explicit Model Binding
The Bind Attribute
The ModelState Dictionary
Adding Custom Errors to the ModelState Dictionary
Controlling Model Binding Sources in ASP.NET Core
Model Validation
Routing
URL Patterns and Route Tokens
Routing and ASP.NET Core Services
Conventional Routing
Named Routes
Attribute Routing
Named Routes
Routing and HTTP Methods
Web Application Routing
API Service Routing
Redirecting Using Routing
Filters
Authorization Filters
Resource Filters
Action Filters
Exception Filters
Result Filters
Add Filters to the Processing Pipeline
What’s New in ASP.NET Core
Built-In Dependency Injection
Cloud-Ready, Environment-Based Configuration System
Determining the Runtime Environment
Application Configuration
Retrieving Settings
Deploying ASP.NET Core Applications
Lightweight and Modular HTTP Request Pipeline
Create and Configure the ASP.NET Core Project
Create the ASP.NET Core Projects
Using Visual Studio
Using the Command Line
Add the NuGetPackages
Add in AutoLot.Dal
Running ASP.NET Core Applications
Using Visual Studio
Using the Command Line
Changing Code While Debugging
Using Visual Studio Code (VSC)
Changing Code While Debugging
Debugging ASP.NET Core Applications
Attaching with Visual Studio
Attaching with Visual Studio Code
Update the AutoLot.Api Ports
Create and Configure the WebHost
The Program.cs File
The Startup.cs File
Available Services for Startup
The Constructor
The ConfigureServices Method
AutoLot.Api
Add the Connection String to the App Settings
AutoLot.Mvc
The Configure Method
AutoLot.Api
Web Applications
Logging Support
Summary
Chapter 30: RESTful Services with ASP.NET Core
Introducing ASP.NET Core RESTful Services
Controller Actions with RESTful Services
Formatted JSON Response Results
The ApiController Attribute
Attribute Routing Requirement
Automatic 400 Responses
Binding Source Parameter Inference
Problem Details for Error Status Codes
Add Swagger/OpenAPI
Add the Swagger Middleware
Add SwaggerGen to the Services Collection
Add the XML Documentation File
Update the Launchsettings.json File
Run and Test the Application
Building the Controllers
The BaseCrudController
The Constructor
The Get Methods
The UpdateOne Method
The AddOne Method
The DeleteOne Method
The CarsController
The Remaining Controllers
Handling Cyclical JSON Serialization
Exception Filters
Create the CustomExceptionFilter
Adding the Exception Filter for All Actions
Test the Exception Filter
Add Cross-Origin Requests Support
Create a CORS Policy
Add the CORS Policy to the HTTP Pipeline Handling
Summary
Chapter 31: MVC Applications with ASP.NET Core
Introducing the “V” in ASP.NET Core
ViewResults
Add the RazorSyntax Action Method
The Razor View Engine
Razor Syntax
Views
The Views Directory
The Shared Directory
The DisplayTemplates Folder
The EditorTemplates Folder
Layouts
Specifying the Default Layout for Views
Partial Views
Sending Data to Views
Strongly Typed Views and View Models
ViewBag, ViewData, and TempData
Tag Helpers
Enabling Tag Helpers
The Form Tag Helper
The Anchor Tag Helper
The Input Tag Helper
The TextArea Tag Helper
The Select Tag Helper
The Validation Tag Helpers
The Link and Script Tag Helpers
The Image Tag Helper
The Environment Tag Helper
Managing Client-Side Libraries
Install Library Manager As a .NET Core Global Tool
Add Client-Side Libraries to AutoLot.Mvc
Add the libman.json File
Visual Studio
Command Line
Update the libman.json File
Bundling and Minification
Bundling
Minification
The WebOptimizer Solution
Update Startup.cs
Update _ViewImports.cshtml
Update the Layout and Partials
Create the Partials
The Header Partial
The Menu Partial
The JavaScript Files Partial
Update the _ValidationScripts Partial
Create the Service Wrapper
Configure the Application
Update the AppSettings.Development.JSON File
Create the ServiceSettings Class
Populate the ServiceSettings Class Using the Services Collection
The Options Pattern in ASP.NET Core
The API Service Wrapper
The IAutoLotServiceWrapper Interface
The AutoLotServiceWrapper Class
The Internal Support Methods
The GetBaseUri Method
The Post and Put Helper Methods
The HTTP Delete Helper Method Call
The HTTP Get Calls
The HTTP Post and Put Calls
The HTTP Delete Call
Add the AutoLotServiceWrapper to the DI Container
View Components
The Server-Side Code
Build the Partial View
Invoking View Components
Invoking View Components As Custom Tag Helpers
Updating the Menu
Run AutoLot.Mvc and AutoLot.Api Together
Using Visual Studio
Using the Command Line
Viewing the Updated Menu
Build the CarsController
The GetMakes Helper Method
The Index Action Method
The ByMake Action Method
The Details Action Method
The Create Action Methods
The Create Get Method
The Create Post Method
The Edit Action Methods
The Edit Get Method
The Edit Post Method
The Delete Action Methods
The Delete Get Method
The Delete Post Method
Add the Custom Tag Helpers
Add the Support Code
Update Startup.cs
Create the String Extension Method
Create the Base Class
The Car Details Tag Helper
The Delete Car Tag Helper
The Edit Car Tag Helper
Making Custom Tag Helpers Visible
Build the Cars Views
The Helper Views
The Car List Partial View
The Car Editor Template
The Car Display Template
The Index View
The ByMake View
The Details View
The Create View
The Edit View
The Delete View
Summary
Index