Constructor Injection vs Property Injection in C#: Key Differences and Usage
constructor injection passes dependencies through a class constructor, ensuring they are set when the object is created. Property injection sets dependencies via public properties after object creation, allowing optional or changeable dependencies.Quick Comparison
This table summarizes the main differences between constructor injection and property injection in C#.
| Factor | Constructor Injection | Property Injection |
|---|---|---|
| Dependency Setup Time | At object creation via constructor | After object creation via property setter |
| Mandatory Dependencies | Enforced by constructor parameters | Not enforced, can be optional |
| Immutability | Dependencies are readonly after construction | Dependencies can be changed anytime |
| Testability | Easier to test with guaranteed dependencies | May require extra setup to ensure dependencies are set |
| Use Case | Required dependencies that must exist | Optional or changeable dependencies |
| Code Clarity | Clear contract of required dependencies | Less explicit, can lead to missing dependencies |
Key Differences
Constructor injection requires all necessary dependencies to be provided when creating an object. This makes the dependencies explicit and guarantees they are available, which helps avoid runtime errors. It also supports immutability because dependencies are set once and cannot be changed later.
In contrast, property injection allows dependencies to be set or changed after the object is created through public properties. This flexibility is useful when dependencies are optional or need to be replaced during the object's lifetime. However, it can lead to errors if dependencies are not set before use, making the code less safe.
Constructor injection promotes clearer and safer code by enforcing dependency requirements upfront, while property injection offers more flexibility but requires careful handling to avoid missing dependencies.
Code Comparison
Here is an example of constructor injection where the dependency is passed through the constructor and stored in a readonly field.
public interface IMessageService { void Send(string message); } public class EmailService : IMessageService { public void Send(string message) { System.Console.WriteLine($"Email sent: {message}"); } } public class Notification { private readonly IMessageService _messageService; public Notification(IMessageService messageService) { _messageService = messageService; } public void Alert(string message) { _messageService.Send(message); } } // Usage var emailService = new EmailService(); var notification = new Notification(emailService); notification.Alert("Hello via constructor injection!");
Property Injection Equivalent
This example shows property injection where the dependency is set via a public property after object creation.
public interface IMessageService { void Send(string message); } public class EmailService : IMessageService { public void Send(string message) { System.Console.WriteLine($"Email sent: {message}"); } } public class Notification { public IMessageService MessageService { get; set; } public void Alert(string message) { if (MessageService == null) { throw new System.InvalidOperationException("MessageService dependency not set."); } MessageService.Send(message); } } // Usage var emailService = new EmailService(); var notification = new Notification(); notification.MessageService = emailService; notification.Alert("Hello via property injection!");
When to Use Which
Choose constructor injection when dependencies are required for the class to function correctly and should not change after creation. This ensures safety, clarity, and immutability.
Choose property injection when dependencies are optional, may change during the object's lifetime, or when you need to avoid complex constructors. Use it carefully to avoid missing dependencies at runtime.