Build on your existing programming skills and upskill to professional-level C# programming.
In Code Like A Pro in C# you will learn:
• Unit testing and test-driven development
• Refactor a legacy .NET codebase
• Principles of clean code
• Essential backend architecture skills
• Query and manipulate databases with LINQ and Entity Framework Core
Critical business applications worldwide are written in the versatile C# language and the powerful .NET platform, running on desktops, cloud systems, and Windows or Linux servers. Code Like a Pro in C# makes it easy to turn your existing abilities in C# or another OO language (such as Java) into practical C# mastery. There’s no “Hello World” or Computer Science 101 basics—you’ll learn by refactoring an out-of-date legacy codebase, using new techniques, tools, and best practices to bring it up to modern C# standards.
About the technology
You know the basics, now get ready for the next step! Pro-quality C# code is efficient, clean, and fast. Whether you’re building user-facing business applications or writing data-intensive backend services, the experience-based, practical techniques in this book will take your C# skills to a new level.
About the book
Code Like a Pro in C# teaches you to how write clean C# code that’s suitable for enterprise applications. In this book, you’ll refactor a legacy codebase by applying modern C# techniques. You’ll explore tools like Entity Framework Core, design techniques like dependency injection, and key practices like testing and clean coding. It’s a perfect path to upgrade your existing C# skills or shift from another OO language into C# and the .NET ecosystem.
What's inside
• Unit testing and test-driven development
• Refactor a legacy .NET codebase
• Principles of clean code
• Query and manipulate databases with LINQ and Entity Framework Core
About the reader
For developers experienced with object-oriented programming. No C# experience required.
About the author
Jort Rodenburg is a software engineer who has taught numerous courses on getting up to speed with C# and .NET.
Author(s): Jort Rodenburg
Edition: 1
Publisher: Manning Publications
Year: 2021
Language: English
Commentary: Vector PDF
Pages: 416
City: Shelter Island, NY
Tags: Programming; Databases; C#; .NET; Web Applications; HTTP; JSON; Best Practices; Object-Oriented Programming; Dependency Injection; Entity Framework
Code Like a Pro in C#
contents
preface
acknowledgments
about this book
Who should read this book
How this book is organized: A roadmap
About the code
liveBook discussion forum
about the author
about the cover illustration
Part 1—Using C# and .NET
1 Introducing C# and .NET
1.1 Why work in C#?
1.1.1 Reason 1: C# is economical
1.1.2 Reason 2: C# is maintainable
1.1.3 Reason 3: C# is developer friendly and easy to use
1.2 Why not work in C#?
1.2.1 Operating system development
1.2.2 Real-time operating system embedded development in C#
1.2.3 Numerical computing and C#
1.3 Switching to C#
1.4 What you will learn in this book
1.5 What you will not learn in this book
Summary
2 .NET and how it compiles
2.1 What is the .NET Framework?
2.2 What is .NET 5?
2.3 How CLI-compliant languages are compiled
2.3.1 Step 1: C# code (high-level)
2.3.2 Step 2: Common Intermediate Language (assembly level)
2.3.3 Step 3: Native code (processor level)
Exercises
Summary
Part 2—The existing codebase
3 How bad is this code?
3.1 Introducing Flying Dutchman Airlines
3.2 Pieces of the puzzle: Taking a look at our requirements
3.2.1 Object-relational mapping
3.2.2 The GET /flight endpoint: Retrieving information on all flights
3.2.3 The GET /flight/{flightNumber} endpoint: Getting specific flight information
3.2.4 The POST /booking/{flightNumber} endpoint: Booking a flight
3.3 Coming to terms with the existing codebase
3.3.1 Assessing the existing database schema and its tables
3.3.2 The existing codebase: Web service configuration files
3.3.3 Considering models and views in the existing codebase
Summary
4 Manage your unmanaged resources!
4.1 The FlightController: Assessing the GET /flight endpoint
4.1.1 The GET /flight endpoint and what it does
4.1.2 Method signature: The meaning of ResponseType and typeof
4.1.3 Collecting flight information with collections
4.1.4 Connection strings, or how to give a security engineer a heart attack
4.1.5 Using IDisposable to release unmanaged resources
4.1.6 Querying a database with SqlCommand
4.2 The FlightController: Assessing GET /flight/{flightNumber}
4.3 The FlightController: POST /flight
4.4 The FlightController: DELETE /flight/{flightNumber}
Exercises
Summary
Part 3—The database access layer
5 Setting up a project and database with Entity Framework Core
5.1 Creating a .NET 5 solution and project
5.2 Setting up and configuring a web service
5.2.1 Configuring a .NET 5 web service
5.2.2 Creating and using HostBuilder
5.2.3 Implementing the Startup class
5.2.4 Using the repository/service pattern for our web service architecture
5.3 Implementing the database access layer
5.3.1 Entity Framework Core and reverse-engineering
5.3.2 DbSet and the Entity Framework Core workflow
5.3.3 Configuration methods and environment variables
5.3.4 Setting an environment variable on Windows
5.3.5 Setting an environment variable on macOS
5.3.6 Retrieving environment variables at run time in your code
Exercises
Summary
Part 4—The repository layer
6 Test-driven development and dependency injection
6.1 Test-driven development
6.2 The CreateCustomer method
6.2.1 Why you should always validate input arguments
6.2.2 Using “arrange, act, assert” to write unit tests
6.2.3 Validating against invalid characters
6.2.4 In-lining test data with the [DataRow] attribute
6.2.5 Object initializers and autogenerated code
6.2.6 Constructors, reflection, and asynchronous programming
6.2.7 Locks, mutexes, and semaphores
6.2.8 Synchronous to asynchronous execution . . . continued
6.2.9 Testing Entity Framework Core
6.2.10 Controlling dependencies with dependency injection
Summary
7 Comparing objects
7.1 The GetCustomerByName method
7.1.1 Question marks: Nullable types and their applications
7.1.2 Custom exceptions, LINQ, and extension methods
7.2 Congruence: From the Middle Ages to C#
7.2.1 Creating a “comparer” class using EqualityComparer
7.2.2 Testing equality by overriding the Equals method
7.2.3 Overloading the equality operator
Exercises
Summary
8 Stubbing, generics, and coupling
8.1 Implementing the Booking repository
8.2 Input validation, separation of concerns, and coupling
8.3 Using object initializers
8.4 Unit testing with stubs
8.5 Programming with generics
8.6 Providing default arguments by using optional parameters
8.7 Conditionals, Func, switches, and switch expressions
8.7.1 The ternary conditional operator
8.7.2 Branching using an array of functions
8.7.3 Switch statements and expressions
8.7.4 Querying for pending changes in Entity Framework Core
Exercises
Summary
9 Extension methods, streams, and abstract classes
9.1 Implementing the Airport repository
9.2 Getting an Airport out of the database by its ID
9.3 Validating the AirportID input parameter
9.4 Output streams and being specifically abstract
9.5 Querying the database for an Airport object
9.6 Implementing the Flight repository
9.6.1 The IsPositive extension method and “magic numbers”
9.6.2 Getting a flight out of the database
Exercises
Summary
Part 5—The service layer
10 Reflection and mocks
10.1 The repository/service pattern revisited
10.1.1 What is the use of a service class?
10.2 Implementing the CustomerService
10.2.1 Setting up for success: Creating skeleton classes
10.2.2 How to delete your own code
10.3 Implementing the BookingService
10.3.1 Unit testing across architectural layers
10.3.2 The difference between a stub and a mock
10.3.3 Mocking a class with the Moq library
10.3.4 Calling a repository from a service
Exercises
Summary
11 Runtime type checking revisited and error handling
11.1 Validating input parameters of a service layer method
11.1.1 Runtime type checks with the is and as operators
11.1.2 Type checking with the is operator
11.1.3 Type checking with the as operator
11.1.4 What did we do in section 11.1?
11.2 Cleaning up the BookingServiceTests class
11.3 Foreign key constraints in service classes
11.3.1 Calling the Flight repository from a service class
Exercises
Summary
12 Using IAsyncEnumerable and yield return
12.1 Do we need an AirportService class?
12.2 Implementing the FlightService class
12.2.1 Getting information on a specific flight from the FlightRepository
12.2.2 Combining two data streams into a view
12.2.3 Using the yield return keywords with try-catch code blocks
12.2.4 Implementing GetFlightByFlightNumber
Exercises
Summary
Part 6—The controller layer
13 Middleware, HTTP routing, and HTTP responses
13.1 The controller class within the repository/service pattern
13.2 Determining what controllers to implement
13.3 Implementing the FlightController
13.3.1 Returning HTTP responses with the IActionResult interface (GetFlights)
13.3.2 Injecting dependencies into a controller using middleware
13.3.3 Implementing the GET /Flight/{FlightNumber} endpoint
13.4 Routing HTTP requests to controllers and methods
Exercises
Summary
14 JSON serialization/ deserialization and custom model binding
14.1 Implementing the BookingController class
14.1.1 Introduction to data deserialization
14.1.2 Using the [FromBody] attribute to deserialize incoming HTTP data
14.1.3 Using a custom model binder and method attribute for model binding
14.1.4 Implementing the CreateBooking endpoint method logic
14.2 Acceptance testing and Swagger middleware
14.2.1 Manual acceptance testing with an OpenAPI specification
14.2.2 Generating an OpenAPI specification at runtime
14.3 The end of the road
Summary
Appendix A—Exercise answers
Chapter 2: .NET and how it compiles
Chapter 4: Manage your unmanaged resources!
Chapter 5: Setting up a project and database with Entity Framework Core
Chapter 6: Test-driven development and dependency injection
Chapter 7: Comparing objects
Chapter 8: Stubbing, generics, and coupling
Chapter 9: Extension methods, streams, and abstract classes
Chapter 10: Reflection and mocks
Chapter 11: Runtime type checking revisited and error handling
Chapter 12: Using IAsyncEnumerable and yield return
Chapter 13: Middleware, HTTP routing, and HTTP responses
Appendix B—Clean code checklist
Appendix C—Installation guides
Appendix D—OpenAPI FlyTomorrow
Appendix E—Reading list
index
Symbols
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
Y