ivankorobkov / python-inject

Python dependency injection
Apache License 2.0
694 stars 79 forks source link

Problems with Injecting Implementations into abstract classes #91

Open cit-alexf opened 11 months ago

cit-alexf commented 11 months ago

Hello.

I'm trying to use python-inject 5.1.0 and I'm unable to inject a class implemented into an abstract class.

class JobGateway: @abstractmethod def get_by_id(self, id: str): pass

class JobGatewayImpl(JobGateway): @inject.autoparams() def init(self, db: Database): self.collection = db["jobs"]

def get_by_id(self, id: str):
    data = self.collection.find_one({"_id": ObjectId(id)})

    if data is None:
        return None

    return data

class MessageProcessor: @inject.autoparams() def init( self, job_gateway: JobGateway ) -> None: self.job_gateway = job_gateway

def run(self, id):
    job = self.job_gateway.get_by_id(id)    

My optional configuration:

binder.bind_to_constructor(JobGateway, lambda: inject.instance(JobGatewayImpl))

When I get a MessageProcessor instance, job_gateway does not get the JobGatewayImpl implementation.

processor: MessageProcessor = inject.instance(MessageProcessor)

But, when I try to get the instance directly, JobGatewayImpl is obtained successfully.

j2: JobGateway = inject.instance(JobGateway)

Why is the JobGatewayImpl implementation not injected into the processor?

AyrtonAlbuquerque commented 6 months ago

Supporting this would be great. This is probably the best dependency injection package for python but this problem with abstract methods (basically interfaces) does not allow for dependency inversion, and they both, injection and inversion, should always be together for a SOLID implementation.

ivankorobkov commented 6 months ago

@AyrtonAlbuquerque thanks.

I will gladly accept a PR if somebody finds a solution and fixes it 🙂