Clean Code with C# Refactor Your Legacy C# Code Base and Improve Application Performance Using Best Practices
Traditionally associated with Windows desktop applications and game development, C# has expanded into web, cloud, and mobile development. However, despite its extensive coding features, professionals often encounter issues with efficiency, scalability, and maintainability due to poor code. Clean Cod...
Otros Autores: | |
---|---|
Formato: | Libro electrónico |
Idioma: | Inglés |
Publicado: |
Birmingham, England :
Packt Publishing Ltd
[2023]
|
Edición: | Second edition |
Materias: | |
Ver en Biblioteca Universitat Ramon Llull: | https://discovery.url.edu/permalink/34CSUC_URL/1im36ta/alma991009790331706719 |
Tabla de Contenidos:
- Cover
- Title page
- Copyright and credits
- Contributors
- Table of Contents
- Preface
- Chapter 1: Coding Standards and Principles in C#
- Technical requirements
- Good code versus bad code
- The need for coding standards, principles, and methodologies
- Coding standards
- Coding principles
- Coding methodologies
- Summary
- Questions
- Further reading
- Chapter 2: Code Review - Process and Importance
- A brief introduction to GitHub
- What is GitHub?
- GitHub's use within the code review process
- Resources for learning
- The code review process
- Preparing code for review
- Leading a code review
- Issuing a pull request
- Responding to a pull request
- Effects of feedback on reviewees
- Knowing what to review
- The company's coding guidelines and business requirement(s)
- Naming conventions
- Formatting
- Testing
- Documentation
- Architectural guidelines and design patterns
- Performance and security
- Knowing when to send code for review
- Providing and responding to review feedback
- Providing feedback as a reviewer
- Responding to feedback as a reviewee
- Summary
- Questions
- Further reading
- Chapter 3: Classes, Objects, and Data Structures
- Technical requirements
- Organizing classes
- A class should have only one responsibility
- Class organization
- Commenting for documentation generation
- Cohesion and coupling
- Tight coupling
- Low coupling
- Low cohesion
- High cohesion
- Designing for change
- Interface-oriented programming
- Dependency injection and inversion of control
- The Law of Demeter
- A good and a bad example (chaining) of the Law of Demeter
- Immutable objects and data structures
- Using records to create immutable objects
- Objects should hide data and expose methods
- An example of encapsulation
- Data structures should expose data and have no methods.
- The SOLID software methodology
- SRP
- Open/closed principle (OCP)
- Liskov substitution principle (LSP)
- Interface segregation principle (ISP)
- Dependency inversion principle (DIP)
- Summary
- Questions
- Further reading
- Chapter 4: Writing Clean Functions
- Technical requirements
- Understanding the difference between OOP and FP
- Explanation of the differences
- Understanding why FP can lead to cleaner functions
- Unclean methods and how they affect software
- FP and clean methods
- FP examples
- Keeping methods small
- Indenting code
- Breaking out of loops
- Avoiding duplication
- Avoiding multiple parameters
- Implementing the SRP
- Handling exceptions in FP
- Adding comments for readability
- XML documentation comments
- Inline comments
- Variable declaration and memory management
- Declaring variables close to their usage
- Disposing of resources
- Applying security in methods, especially in APIs
- Input validation
- Authentication and authorization
- Protecting sensitive data
- Summary
- Questions
- Further reading
- Chapter 5: Exception Handling
- Technical requirements
- Overview of exception handling in C#
- try-catch
- try-catch-finally
- Clean code exception-handling principles
- SRP
- OCP
- DIP
- Best practices for handling exceptions
- Handling the TPL AggregateException exception
- Use await with try-catch inside async methods
- Flatten the exception hierarchy
- Handle individual exceptions
- Handle exceptions as they occur
- Creating custom exceptions and when to use them
- Avoiding common mistakes in exception handling
- Testing exception handling
- Unit testing exception handling
- Integration testing exception handling
- End-to-end testing exception handling
- An employee management example of mocking and unit testing with correct exception handling
- Summary.
- Questions
- Further reading
- Chapter 6: Unit Testing
- Technical requirements
- Understanding unit testing
- Writing testable code
- TDD
- An example of using the AAA TDD pattern
- Choosing a testing framework
- Testing framework attribute differences
- TDD using MSTest
- TDD using NUnit
- TDD using xUnit
- Running tests in Visual Studio
- Writing effective unit tests
- Using code coverage analysis in Visual Studio 2022
- Ensuring your unit tests themselves are correct
- Using stubs in place of mocks
- Mocking data
- Integrating tests into the continuous integration and deployment (CI/CD) pipeline
- Integrating tests into an Azure DevOps CI/CD pipeline
- Problem tests
- Summary
- Questions
- Further reading
- Chapter 7: Designing and Developing APIs
- Technical requirements
- What is an API?
- APIs help different consumers build loosely coupled applications
- Idempotent and non-idempotent operations
- HTTP verbs
- Important API design topics you must consider
- How can clean code help API design and development?
- The API design process
- API security risks and their mitigations
- On-premises APIs versus cloud APIs
- API development in C#
- Web API security with OWASP
- Importance of OWASP adherence in C# API development
- Creating an OWASP-compliant API
- Implementing OWASP-compliant two-factor authentication (2FA)
- OpenID Connect (OIDC) and OAuth 2.0 (OAuth2)
- Summary
- Questions
- Further reading
- Chapter 8: Addressing Cross-Cutting Concerns
- A definition of cross-cutting concerns
- Importance and impact on software development
- Common examples of cross-cutting concerns
- Logging
- Error handling and exception management
- Caching
- Performance optimization
- Transaction management
- Validation
- Auditing and compliance
- Localization and internationalization
- Logging and monitoring.
- Summary
- Questions
- Further reading
- Chapter 9: AOP with PostSharp
- Technical requirements
- AOP
- AOP frameworks
- How AOP works with PostSharp
- Extending the aspect framework
- Project - Cross-cutting concerns reusable library
- Adding a caching concern
- Adding file logging capabilities
- Adding an exception-handling concern
- Adding a security concern
- Adding a validation concern
- Adding a transaction concern
- Adding a resource pool concern
- Adding a configuration settings concern
- Adding an instrumentation concern
- PostSharp and build pipeline considerations
- Dynamic AOP with Castle.DynamicProxy
- Summary
- Questions
- Further reading
- Chapter 10: Using Tools to Improve Code Quality
- Technical requirements
- Code analysis
- Using quick actions
- Using the JetBrains dotTrace profiler
- Using JetBrains ReSharper
- Using Telerik JustDecompile
- Continuous integration with GitHub Actions and CodeQL
- Summary
- Questions
- Further reading
- Chapter 11: Refactoring C# Code
- Technical requirements
- Application-level code smells
- Boolean blindness
- Combinatorial explosion
- Contrived complexity
- Data clump
- Deodorant comments
- Duplicate code
- Lost intent
- The mutation of variables
- The oddball solution
- Shotgun surgery
- Solution sprawl
- Uncontrolled side effects
- Class-level code smells
- Cyclomatic complexity
- Divergent change
- Downcasting
- Excessive literal use
- Feature envy
- Inappropriate intimacy
- Indecent exposure
- The large class (the God object)
- The lazy class (the freeloader and the lazy object)
- The middleman class
- The orphan class of variables and constants
- Primitive obsession
- Refused bequest
- Speculative generality
- Tell, Don't Ask
- Temporary fields
- Method-level smells
- The black sheep method
- Cyclomatic complexity.
- Contrived complexity
- Dead code
- Excessive data return
- Feature envy
- Identifier size
- Inappropriate intimacy
- Long lines (God lines)
- Lazy methods
- Long methods (God methods)
- Long parameter lists (too many parameters)
- Message chains
- The middleman method
- Oddball solutions
- Speculative generality
- Summary
- Questions
- Further reading
- Chapter 12: Functional Programming
- Technical requirements
- Imperative versus functional programming
- Imperative programming
- Key differences
- Overview of functional programming in C#
- First-class functions and Lambda expressions
- Lambda expressions in C#
- Higher-order functions
- Immutability and pure functions
- Functional composition
- Using Lambda expressions
- Using LINQ and extension methods
- Using higher-order functions
- Option types and the Maybe monad
- Usage of option types in C#
- The Maybe monad in C#
- Functional error handling
- Option types
- The Maybe monad
- The Either monad
- Result objects
- Functional data transformation and pipelines
- Lazy evaluation
- Pattern matching
- Currying and partial application
- Currying
- Partial application
- Key differences
- Concurrency with functional programming
- Recursion
- Summary
- Questions
- Further reading
- Chapter 13: Cross-Platform Application Development with MAUI
- Technical requirements
- Project overview
- Windows version
- Android version
- Creating the project
- Understanding XAML structure
- The MVVM pattern
- Adding CommunityToolkit.Mvvm
- The models
- The ViewModels
- The views
- Configuring our to-do application
- Summary
- Questions
- Further reading
- Chapter 14: Microservices
- What are microservices?
- The downsides of microservices, some gotchas experienced by microservices, and how they can be overcome and avoided.
- Comparison between microservices and monoliths.