ivankorobkov / python-inject

Python dependency injection
Apache License 2.0
671 stars 77 forks source link

Register classes programmatically #59

Open dbalabka opened 4 years ago

dbalabka commented 4 years ago

Is it possible to register classes in the same way as @inject.autoparams provides but programmatically inside configuration callback?

For example:


def configure(binder: Binder):
    binder.bind_to_constructor(SomeClass, inject.autoparams()(SomeClass.__init__))

inject.configure(configure)

This example will throw an error:

TypeError: __init__() missing 1 required positional argument: 'self'
dbalabka commented 4 years ago

@ivankorobkov in PR #60 I have implemented that possibility.

Now it is possible in following way:

def configure(binder: Binder):
    binder.bind_to_constructor(SomeClass, inject.autoparams()(SomeClass))

inject.configure(configure)
dbalabka commented 4 years ago

@ivankorobkov it would be great to have the possibility to use inject.autoparams as a class decorator. Probably it will require separate decorator for classes.

The following test will fail because classes AnotherClass and SomeClass became decorated and are functions:

    def test_class_support_in_autoparams_decorator(self):
        @autoparams()
        class AnotherClass:
            pass

        @autoparams()
        class SomeClass:
            def __init__(self, another_object: AnotherClass):
                self.another_object = another_object

        inject.configure()
        some_object = inject.instance(SomeClass)
        assert isinstance(some_object, SomeClass)
        assert isinstance(some_object.another_object, AnotherClass)

To properly solve this issue we should return child class of AnotherClass and SomeClass decorator instead.