Beyond Rigid Constructors Many developers trap themselves by initializing dependencies directly inside a class. This creates tight coupling, where a change in a low-level service forces a rewrite of high-level logic. For instance, an `EmailSender` class that creates its own MailChimp or SendGrid objects must know the specific arguments those services require. If MailChimp suddenly needs an API key or an attachment flag, you have to modify the sender's core logic. This violates the Open-Closed Principle and makes your codebase a brittle mess. The Dependency Injection Pattern Dependency Injection flips the script. Instead of a class "reaching out" to build what it needs, you "hand" the dependencies to the class. This typically happens in the `__init__` method. By injecting a service that follows a specific Python Protocol, your class remains blissfully unaware of implementation details. It only cares that the object it receives has a `send_email` method. Code Walkthrough: Before and After The Coupled Approach In the rigid version, an `if-else` block determines which service to instantiate. This grows uncontrollably as you add new providers like Mailgun. ```python class EmailSender: def send_email(self, service_type, to, subject, body): if service_type == "mailchimp": service = MailChimp(attachment=True) elif service_type == "sendgrid": service = SendGrid() service.send(to, subject, body) ``` The Injected Approach By moving the service creation outside the class, we achieve a clean, single-purpose method. ```python class EmailSender: def __init__(self, service: EmailService): self.service = service def send_email(self, to, subject, body): self.service.send(to, subject, body) ``` Syntax and Best Practices Use Python's typing.Protocol to define a contract for your services. This ensures type-safety without strict inheritance. When writing unit tests, this pattern is a lifesaver. You can inject a mock service that doesn't actually send emails, allowing you to test the `EmailSender` logic in isolation without dealing with Pytest monkeypatching or network calls. This leads to faster, more reliable test suites and modular code that survives architectural shifts.
SendGrid
Products
- Feb 27, 2024
- Aug 25, 2023