When you need multiple instances of a single type (e.g., a primary database and a read replica), you can control which instance is injected using either Explicit Definitions or Subtyping.
Approach 1: Explicit Definitions
This is the simplest method and requires minimal changes to your existing codebase. You manually tell the Container how to construct each class by providing a lambda or factory function that specifies the correct arguments.
Approach 2: Subtyping
This approach involves creating subclasses for each specific instance type (e.g., PrimaryDb and ReadReplica inheriting from Database). You then update your domain code to type hint the specific subclass instead of the base class. This method is more explicit, follows standard Python patterns, and allows IDEs and static analysis tools to correctly identify dependencies.
# Approach 1: Explicit Definitions
from lagom import Container
container = Container()
container[QueryService] = lambda: QueryService(Database("read-replica-connection-string"))
container[DataWriter] = lambda: DataWriter(Database("primary-connection-string"))
# Approach 2: Subtyping
class PrimaryDb(Database):
pass
class ReadReplica(Database):
pass
container[ReadReplica] = lambda: ReadReplica("read-replica-connection-string")
container[PrimaryDb] = lambda: PrimaryDb("primary-connection-string")
class QueryService:
def __init__(self, db: ReadReplica):
pass