使用Property Injection时,如何理解“Local Defaults”?
Great question—this is a nuanced point from Mark Seemann's Dependency Injection in .NET that trips up a lot of folks when they first encounter property injection. Let's break down what Local Defaults means in this context, and why it's a key condition for using property injection.
What are Local Defaults?
In the context of property injection, a Local Default is a concrete, functional implementation of a dependency that the class itself provides out of the box. This implementation lives "locally" to the class (either as a direct assignment or created within the class) and acts as a fallback: if no external dependency is injected via the property, the class can still operate correctly using this default.
This is a critical distinction from constructor injection, where dependencies are typically required and no local fallback exists—if you don't provide them, the class can't be instantiated at all.
Example of Local Defaults in Code
Let's use a simple C# example to make this concrete, aligned with Seemann's guidance:
public class OrderProcessor { // Here, ConsoleLogger is the Local Default for the ILogger dependency public ILogger Logger { get; set; } = new ConsoleLogger(); public void ProcessOrder(Order order) { // Even if no external Logger is injected, this line works with the default Logger.LogInfo($"Starting processing for order {order.Id}"); // Core order processing logic... } } // The default implementation used as the Local Default public class ConsoleLogger : ILogger { public void LogInfo(string message) => Console.WriteLine($"INFO: {message}"); }
In this case:
- The
OrderProcessordoesn't require an externalILoggerto be injected. - If a DI container (or manual code) sets the
Loggerproperty to a different implementation (like aFileLogger), it will use that instead. - If nothing is injected, it falls back to the local
ConsoleLoggerand still functions as expected.
Why Local Defaults Matter for Property Injection
Seemann highlights this condition because property injection should only be used when:
- The dependency is optional (the class can work without it, or with a default)
- A Local Default exists (so the class doesn't rely on external systems to provide a fallback)
This keeps your class robust: it's not dependent on a DI container to function, which makes it easier to test in isolation and use outside of a DI context. It also signals to other developers that the dependency isn't strictly required for the class's core functionality.
内容的提问来源于stack exchange,提问作者kaszm

