Here are 10 Python code snippets demonstrating dependency injection techniques that help with managing dependencies in Python applications to improve flexibility and testability:
1. Basic Constructor Injection
classDatabase:defconnect(self):return"Connected to the database."classService:def__init__(self,db: Database):self.db = dbdefget_data(self):returnself.db.connect()# Creating instancesdb =Database()service =Service(db)print(service.get_data())
2. Dependency Injection via Setter Method
3. Dependency Injection with Function Injection
4. Using Dependency Injection with a Context Manager
5. Dependency Injection via a Factory Function
6. Using Dependency Injection with a Simple DI Container
7. Using Dependency Injection with Class Inheritance
8. Using Dependency Injection with Abstract Base Classes
9. Dependency Injection for Unit Testing
10. Using Dependency Injection with injector Library
Install injector with pip install injector.
These examples show various ways to implement dependency injection in Python, including constructor injection, setter injection, factory methods, DI containers, and using popular libraries like injector. Dependency injection helps to decouple components and makes code more testable and flexible.
class Database:
def connect(self):
return "Connected to the database."
class Service:
def set_db(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
# Creating instances
db = Database()
service = Service()
service.set_db(db)
print(service.get_data())
def service_function(db: Database):
return db.connect()
class Database:
def connect(self):
return "Connected to the database."
# Create the dependency instance and inject it
db = Database()
print(service_function(db))
from contextlib import contextmanager
class Database:
def connect(self):
return "Connected to the database."
@contextmanager
def service_context():
db = Database()
yield db
# Cleanup if needed
with service_context() as db:
print(db.connect())
class Database:
def connect(self):
return "Connected to the database."
class Service:
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
def create_service():
db = Database()
return Service(db)
# Creating and using the service
service = create_service()
print(service.get_data())
class Database:
def connect(self):
return "Connected to the database."
class Service:
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
class Container:
def __init__(self):
self._services = {}
def register(self, name, instance):
self._services[name] = instance
def get(self, name):
return self._services[name]
# Registering and using services
container = Container()
container.register("db", Database())
container.register("service", Service(container.get("db")))
service = container.get("service")
print(service.get_data())
class Database:
def connect(self):
return "Connected to the database."
class Service:
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
class MyService(Service):
def __init__(self, db: Database):
super().__init__(db)
# Creating instances
db = Database()
service = MyService(db)
print(service.get_data())
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def connect(self):
pass
class MySQLDatabase(Database):
def connect(self):
return "Connected to MySQL database."
class Service:
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
# Creating instances
db = MySQLDatabase()
service = Service(db)
print(service.get_data())
class Database:
def connect(self):
return "Connected to the database."
class Service:
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
# Mock Database class for testing
class MockDatabase:
def connect(self):
return "Mock database connection."
# Unit Test
def test_service():
mock_db = MockDatabase()
service = Service(mock_db)
assert service.get_data() == "Mock database connection."
test_service()
from injector import inject, Injector, Module, provider
class Database:
def connect(self):
return "Connected to the database."
class Service:
@inject
def __init__(self, db: Database):
self.db = db
def get_data(self):
return self.db.connect()
class MyModule(Module):
@provider
def provide_database(self) -> Database:
return Database()
# Creating injector and running the application
injector = Injector([MyModule()])
service = injector.get(Service)
print(service.get_data())