Dependency Injection Principles, Practices, and Patterns

Book Description

Dependency Injection Principles, Practices, and Patterns is a revised and expanded edition of the bestselling classic Dependency Injection in .NET. It teaches you DI from the ground up, featuring relevant examples, patterns, and anti-patterns for creating loosely coupled, well-structured applications. The well-annotated code and diagrams use C# examples to illustrate principles that work flawlessly with modern object-oriented languages and DI libraries.

Table of Contents

  1. Cover
  2. Titlepage
  3. Copyright
  4. Brief Contents
  5. Contents
  6. praise for the first edition
  7. preface
  8. acknowledgments
  9. about this book
    1. Who should read this book?
    2. Roadmap
    3. Code conventions and downloads
    4. liveBook discussion forum
  10. about the authors
  11. about the cover illustration
  12. Part 1: Putting Dependency Injection on the map
    1. Chapter 1: The basics of Dependency Injection: What, why, and how
      1. 1.1 Writing maintainable code
        1. 1.1.1 Common myths about DI
        2. 1.1.2 Understanding the purpose of DI
      2. 1.2 A simple example: Hello DI!
        1. 1.2.1 Hello DI! code
        2. 1.2.2 Benefits of DI
      3. 1.3 What to inject and what not to inject
        1. 1.3.1 Stable Dependencies
        2. 1.3.2 Volatile Dependencies
      4. 1.4 DI scope
        1. 1.4.1 Object Composition
        2. 1.4.2 Object Lifetime
        3. 1.4.3 Interception
        4. 1.4.4 DI in three dimensions
      5. 1.5 Conclusion
      6. Summary
    2. Chapter 2: Writing tightly coupled code
      1. 2.1 Building a tightly coupled application
        1. 2.1.1 Meet Mary Rowan
        2. 2.1.2 Creating the data layer
        3. 2.1.3 Creating the domain layer
        4. 2.1.4 Creating the UI layer
      2. 2.2 Evaluating the tightly coupled application
        1. 2.2.1 Evaluating the dependency graph
        2. 2.2.2 Evaluating composability
      3. 2.3 Analysis of missing composability
        1. 2.3.1 Dependency graph analysis
        2. 2.3.2 Data access interface analysis
        3. 2.3.3 Miscellaneous other issues
      4. 2.4 Conclusion
      5. Summary
    3. Chapter 3: Writing loosely coupled code
      1. 3.1 Rebuilding the e-commerce application
        1. 3.1.1 Building a more maintainable UI
        2. 3.1.2 Building an independent domain model
        3. 3.1.3 Building a new data access layer
        4. 3.1.4 Implementing an ASP.NET Core–specific IUserContext Adapter
        5. 3.1.5 Composing the application in the Composition Root
      2. 3.2 Analyzing the loosely coupled implementation
        1. 3.2.1 Understanding the interaction between components
        2. 3.2.2 Analyzing the new dependency graph
      3. Summary
  13. Part 2: Catalog
    1. Chapter 4: DI patterns
      1. 4.1 Composition Root
        1. 4.1.1 How Composition Root works
        2. 4.1.2 Using a DI Container in a Composition Root
        3. 4.1.3 Example: Implementing a Composition Root using Pure DI
        4. 4.1.4 The apparent dependency explosion
      2. 4.2 Constructor Injection
        1. 4.2.1 How Constructor Injection works
        2. 4.2.2 When to use Constructor Injection
        3. 4.2.3 Known use of Constructor Injection
        4. 4.2.4 Example: Adding currency conversions to the featured products
        5. 4.2.5 Wrap-up
      3. 4.3 Method Injection
        1. 4.3.1 How Method Injection works
        2. 4.3.2 When to use Method Injection
        3. 4.3.3 Known use of Method Injection
        4. 4.3.4 Example: Adding currency conversions to the ProductEntity
      4. 4.4 Property Injection
        1. 4.4.1 How Property Injection works
        2. 4.4.2 When to use Property Injection
        3. 4.4.3 Known uses of Property Injection
        4. 4.4.4 Example: Property Injection as an extensibility model of a reusable library
      5. 4.5 Choosing which pattern to use
      6. Summary
    2. Chapter 5: DI anti-patterns
      1. 5.1 Control Freak
        1. 5.1.1 Example: Control Freak through newing up Dependencies
        2. 5.1.2 Example: Control Freak through factories
        3. 5.1.3 Example: Control Freak through overloaded constructors
        4. 5.1.4 Analysis of Control Freak
      2. 5.2 Service Locator
        1. 5.2.1 Example: ProductService using a Service Locator
        2. 5.2.2 Analysis of Service Locator
      3. 5.3 Ambient Context
        1. 5.3.1 Example: Accessing time through Ambient Context
        2. 5.3.2 Example: Logging through Ambient Context
        3. 5.3.3 Analysis of Ambient Context
      4. 5.4 Constrained Construction
        1. 5.4.1 Example: Late binding a ProductRepository
        2. 5.4.2 Analysis of Constrained Construction
      5. Summary
    3. Chapter 6: Code smells
      1. 6.1 Dealing with the Constructor Over-injection code smell
        1. 6.1.1 Recognizing Constructor Over-injection
        2. 6.1.2 Refactoring from Constructor Over-injection to Facade Services
        3. 6.1.3 Refactoring from Constructor Over-injection to domain events
      2. 6.2 Abuse of Abstract Factories
        1. 6.2.1 Abusing Abstract Factories to overcome lifetime problems
        2. 6.2.2 Abusing Abstract Factories to select Dependencies based on runtime data
      3. 6.3 Fixing cyclic Dependencies
        1. 6.3.1 Example: Dependency cycle caused by an SRP violation
        2. 6.3.2 Analysis of Mary’s Dependency cycle
        3. 6.3.3 Refactoring from SRP violations to resolve the Dependency cycle
        4. 6.3.4 Common strategies for breaking Dependency cycles
        5. 6.3.5 Last resort: Breaking the cycle with Property Injection
      4. Summary
  14. Part 3: Pure DI
    1. Chapter 7: Application composition
      1. 7.1 Composing console applications
        1. 7.1.1 Example: Updating currencies using the UpdateCurrency program
        2. 7.1.2 Building the Composition Root of the UpdateCurrency program
        3. 7.1.3 Composing object graphs in CreateCurrencyParser
        4. 7.1.4 A closer look at UpdateCurrency’s layering
      2. 7.2 Composing UWP applications
        1. 7.2.1 UWP composition
        2. 7.2.2 Example: Wiring up a product-management rich client
        3. 7.2.3 Implementing the Composition Root in the UWP application
      3. 7.3 Composing ASP.NET Core MVC applications
        1. 7.3.1 Creating a custom controller activator
        2. 7.3.2 Constructing custom middleware components using Pure DI
      4. Summary
    2. Chapter 8: Object lifetime
      1. 8.1 Managing Dependency Lifetime
        1. 8.1.1 Introducing Lifetime Management
        2. 8.1.2 Managing lifetime with Pure DI
      2. 8.2 Working with disposable Dependencies
        1. 8.2.1 Consuming disposable Dependencies
        2. 8.2.2 Managing disposable Dependencies
      3. 8.3 Lifestyle catalog
        1. 8.3.1 The Singleton Lifestyle
        2. 8.3.2 The Transient Lifestyle
        3. 8.3.3 The Scoped Lifestyle
      4. 8.4 Bad Lifestyle choices
        1. 8.4.1 Captive Dependencies
        2. 8.4.2 Using Leaky Abstractions to leak Lifestyle choices to consumers
        3. 8.4.3 Causing concurrency bugs by tying instances to the lifetime of a thread
      5. Summary
    3. Chapter 9: Interception
      1. 9.1 Introducing Interception
        1. 9.1.1 Decorator design pattern
        2. 9.1.2 Example: Implementing auditing using a Decorator
      2. 9.2 Implementing Cross-Cutting Concerns
        1. 9.2.1 Intercepting with a Circuit Breaker
        2. 9.2.2 Reporting exceptions using the Decorator pattern
        3. 9.2.3 Preventing unauthorized access to sensitive functionality using a Decorator
      3. Summary
    4. Chapter 10: Aspect-Oriented Programming by design
      1. 10.1 Introducing AOP
      2. 10.2 The SOLID principles
        1. 10.2.1 Single Responsibility Principle (SRP)
        2. 10.2.2 Open/Closed Principle (OCP)
        3. 10.2.3 Liskov Substitution Principle (LSP)
        4. 10.2.4 Interface Segregation Principle (ISP)
        5. 10.2.5 Dependency Inversion Principle (DIP)
        6. 10.2.6 SOLID principles and Interception
      3. 10.3 SOLID as a driver for AOP
        1. 10.3.1 Example: Implementing product-related features using IProductService
        2. 10.3.2 Analysis of IProductService from the perspective of SOLID
        3. 10.3.3 Improving design by applying SOLID principles
        4. 10.3.4 Adding more Cross-Cutting Concerns
        5. 10.3.5 Conclusion
      4. Summary
    5. Chapter 11: Tool-based Aspect-Oriented Programming
      1. 11.1 Dynamic Interception
        1. 11.1.1 Example: Interception with Castle Dynamic Proxy
        2. 11.1.2 Analysis of dynamic Interception
      2. 11.2 Compile-time weaving
        1. 11.2.1 Example: Applying a transaction aspect using compile-time weaving
        2. 11.2.2 Analysis of compile-time weaving
      3. Summary
  15. Part 4: DI Containers
    1. Chapter 12: DI Container introduction
      1. 12.1 Introducing DI Containers
        1. 12.1.1 Exploring containers’ Resolve API
        2. 12.1.2 Auto-Wiring
        3. 12.1.3 Example: Implementing a simplistic DI Container that supports Auto-Wiring
      2. 12.2 Configuring DI Containers
        1. 12.2.1 Configuring containers with configuration files
        2. 12.2.2 Configuring containers using Configuration as Code
        3. 12.2.3 Configuring containers by convention using Auto-Registration
        4. 12.2.4 Mixing and matching configuration approaches
      3. 12.3 When to use a DI Container
        1. 12.3.1 Using third-party libraries involves costs and risks
        2. 12.3.2 Pure DI gives a shorter feedback cycle
        3. 12.3.3 The verdict: When to use a DI Container
      4. Summary
    2. Chapter 13: The Autofac DI Container
      1. 13.1 Introducing Autofac
        1. 13.1.1 Resolving objects
        2. 13.1.2 Configuring the ContainerBuilder
      2. 13.2 Managing lifetime
        1. 13.2.1 Configuring instance scopes
        2. 13.2.2 Releasing components
      3. 13.3 Registering difficult APIs
        1. 13.3.1 Configuring primitive Dependencies
        2. 13.3.2 Registering objects with code blocks
      4. 13.4 Working with multiple components
        1. 13.4.1 Selecting among multiple candidates
        2. 13.4.2 Wiring sequences
        3. 13.4.3 Wiring Decorators
        4. 13.4.4 Wiring Composites
      5. Summary
    3. Chapter 14: The Simple Injector DI Container
      1. 14.1 Introducing Simple Injector
        1. 14.1.1 Resolving objects
        2. 14.1.2 Configuring the container
      2. 14.2 Managing lifetime
        1. 14.2.1 Configuring Lifestyles
        2. 14.2.2 Releasing components
        3. 14.2.3 Ambient scopes
        4. 14.2.4 Diagnosing the container for common lifetime problems
      3. 14.3 Registering difficult APIs
        1. 14.3.1 Configuring primitive Dependencies
        2. 14.3.2 Extracting primitive Dependencies to Parameter Objects
        3. 14.3.3 Registering objects with code blocks
      4. 14.4 Working with multiple components
        1. 14.4.1 Selecting among multiple candidates
        2. 14.4.2 Wiring sequences
        3. 14.4.3 Wiring Decorators
        4. 14.4.4 Wiring Composites
        5. 14.4.5 Sequences are streams
      5. Summary
    4. Chapter 15: The Microsoft.Extensions.DependencyInjection DI Container
      1. 15.1 Introducing Microsoft.Extensions.DependencyInjection
        1. 15.1.1 Resolving objects
        2. 15.1.2 Configuring the ServiceCollection
      2. 15.2 Managing lifetime
        1. 15.2.1 Configuring Lifestyles
        2. 15.2.2 Releasing components
      3. 15.3 Registering difficult APIs
        1. 15.3.1 Configuring primitive Dependencies
        2. 15.3.2 Extracting primitive Dependencies to Parameter Objects
        3. 15.3.3 Registering objects with code blocks
      4. 15.4 Working with multiple components
        1. 15.4.1 Selecting among multiple candidates
        2. 15.4.2 Wiring sequences
        3. 15.4.3 Wiring Decorators
        4. 15.4.4 Wiring Composites
      5. Summary
  16. Glossary
  17. Resources
  18. Index
  19. List of Figures
  20. List of Tables
  21. List of Listings

Product Information

  • Title: Dependency Injection Principles, Practices, and Patterns
  • Author(s): Steven van Deursen, Mark Seemann
  • Release date: March 2019
  • Publisher(s): Manning Publications
  • ISBN: 9781617294730