ets-labs / python-dependency-injector

Dependency injection framework for Python
https://python-dependency-injector.ets-labs.org/
BSD 3-Clause "New" or "Revised" License
3.86k stars 303 forks source link

Circularly interrelated packages #766

Open Arseniy-Popov opened 10 months ago

Arseniy-Popov commented 10 months ago

When using subcontainers to organize layers in an application, there likely won't be circular dependencies between them. However, with domains this is not the case.

@dataclass
class UserService:
    payments: "PaymentsService"

    def user_action(self):
        print("user action")
        self.payments.payment_action

@dataclass
class PaymentsService:
    users: UserService

    def payment_action(self):
        print("payment action")

class UserContainer(containers.DeclarativeContainer):
    payments = providers.DependenciesContainer()

    service = providers.Factory(UserService, payments=payments.service)

class PaymentContainer(containers.DeclarativeContainer):
    users = providers.DependenciesContainer()

    service = providers.Factory(PaymentsService, users=users.service)

class ApplicationContainer(containers.DeclarativeContainer):
    users = providers.Container(UserContainer, payments=???)
    payments = providers.Container(PaymentContainer, users=users)

What's there to do if in the outermost container I want to link packages with circular dependencies between them?

philipbjorge commented 9 months ago

I'm not the maintainer, but let me share my experience using this library...

One of the explicit benefits of containers.DeclarativeContainer is that it prevents circular dependencies. You end up with a tree of dependencies instead of a cyclical graph (spaghetti).

In our application, our Users service actually has no dependencies, so I'm wondering if you might restructure your application in this way.

If you need circular dependencies for some reason (we've run into this with libraries on occasion), using the @inject style of injection can work in conjunction with string identifiers.