diff --git a/docs/images/providers/factory_init_injections.png b/docs/images/providers/factory_init_injections.png index 8a104712..b7a4f1fd 100644 Binary files a/docs/images/providers/factory_init_injections.png and b/docs/images/providers/factory_init_injections.png differ diff --git a/docs/images/providers/factory_init_injections_and_contexts.png b/docs/images/providers/factory_init_injections_and_contexts.png index 2eb6c328..3945e923 100644 Binary files a/docs/images/providers/factory_init_injections_and_contexts.png and b/docs/images/providers/factory_init_injections_and_contexts.png differ diff --git a/docs/providers/factory.rst b/docs/providers/factory.rst index 01e431e8..5f9c6109 100644 --- a/docs/providers/factory.rst +++ b/docs/providers/factory.rst @@ -12,42 +12,33 @@ Nothing could be better than brief example: .. literalinclude:: ../../examples/providers/factory.py :language: python -Factory providers and injections -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Objects can take dependencies in different forms. Some objects take init -arguments, other are using attributes setting or method calls to be -initialized. It affects how such objects need to be created and initialized, -and that is the place where ``dependency_injector.injections`` need to be used. - -``Factory`` provider takes various number of positional arguments, that define -what kind of dependency injections need to be done. - -All of those instructions are defined in ``dependency_injector.injections`` -module and are subclasses of ``dependency_injector.injections.Injection``. -There are several types of injections that are used by ``Factory`` provider: - -+ ``KwArg`` - injection is done by passing injectable value in object's - ``__init__()`` method in time of object's creation via keyword argument. - Takes keyword name of ``__init__()`` argument and injectable value. -+ ``Attribute`` - injection is done by setting specified attribute with - injectable value right after object's creation. Takes attribute's name - and injectable value. -+ ``Method`` - injection is done by calling of specified method with - injectable value right after object's creation and attribute injections - are done. Takes method name and injectable value. - -All ``Injection``'s injectable values are provided *"as is"*, except of -providers. Providers will be called every time, when injection needs to be -done. - - Factory providers and __init__ injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Example below shows how to create ``Factory`` of particular class with -``__init__`` keyword argument injections which injectable values are also -provided by another factories: +``di.Factory`` takes a various number of keyword arguments that are +transformed into keyword argument injections. Every time, when ``di.Factory`` +creates new one instance, keyword argument injections would be passed as an +instance's keyword arguments. + +All injectable values are provided *"as is"*, except of providers (subclasses +of ``di.Provider``). Providers will be called every time, when injection needs +to be done. For example, if injectable value of keyword argument injection is a +``di.Factory``, it will provide new one instance (as a result of its call) as +an injectable value every time, when injection needs to be done. + +Example below is a little bit more complicated. It shows how to create +``di.Factory`` of particular class with ``__init__`` keyword argument +injections which injectable values are also provided by another factories: + +.. note:: + + Current keyword argument injections syntax (in an example below) is a + **simplified one**. Full syntax and other types of injections could be + found in sections below. + + While keyword argument injections may be the best way of passing + injections, current simplified syntax might be the preferable one and + could be widely used. .. image:: /images/providers/factory_init_injections.png :width: 90% @@ -56,11 +47,14 @@ provided by another factories: .. literalinclude:: ../../examples/providers/factory_init_injections.py :language: python -Next example shows how ``Factory`` provider deals with positional and keyword -``__init__`` context arguments. In few words, ``Factory`` provider fully -passes positional context arguments to class's ``__init__`` method, but -keyword context arguments have priority on ``KwArg`` injections (this could be -useful for testing). +Factory providers and __init__ injections priority +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Next example shows how ``di.Factory`` provider deals with positional and +keyword ``__init__`` context arguments. In few words, ``di.Factory`` +provider fully passes positional context arguments to class's ``__init__`` +method, but keyword context arguments have priority on predefined keyword +argument injections. So, please, follow the example below: @@ -69,6 +63,35 @@ So, please, follow the example below: .. literalinclude:: ../../examples/providers/factory_init_injections_and_contexts.py :language: python + +Factory providers and other types of injections +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Objects can take dependencies in different forms(some objects take init +arguments, other use attributes setting or method calls). It affects how +such objects are created and initialized. + +``di.Factory`` provider takes various number of positional and keyword +arguments, that define what kinds of dependency injections have to be used. + +All of those instructions are defined in ``di.injections`` module and are +subclasses of ``di.injections.Injection`` (shortcut ``di.Injection``). There +are several types of injections that are used by ``di.Factory`` provider: + ++ ``di.KwArg`` - injection is done by passing injectable value in object's + ``__init__()`` method in time of object's creation via keyword argument. + Takes keyword name of ``__init__()`` argument and injectable value. ++ ``di.Attribute`` - injection is done by setting specified attribute with + injectable value right after object's creation. Takes attribute's name + and injectable value. ++ ``di.Method`` - injection is done by calling of specified method with + injectable value right after object's creation and attribute injections + are done. Takes method name and injectable value. + +All ``di.Injection``'s injectable values are provided *"as is"*, except of +providers (subclasses of ``di.Provider``). Providers will be called every time, +when injection needs to be done. + Factory providers and attribute injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/examples/providers/factory_init_injections.py b/examples/providers/factory_init_injections.py index adef160e..cc45751e 100644 --- a/examples/providers/factory_init_injections.py +++ b/examples/providers/factory_init_injections.py @@ -1,7 +1,6 @@ -"""`Factory` providers with init injections example.""" +"""`di.Factory` providers with init injections example.""" -from dependency_injector.providers import Factory -from dependency_injector.injections import KwArg +import dependency_injector as di class User(object): @@ -19,9 +18,9 @@ class Photo(object): """Example class Photo.""" # User and Photo factories: -photos_factory = Factory(Photo) -users_factory = Factory(User, - KwArg('main_photo', photos_factory)) +photos_factory = di.Factory(Photo) +users_factory = di.Factory(User, + main_photo=photos_factory) # Creating several User objects: user1 = users_factory() # Same as: user1 = User(main_photo=Photo()) diff --git a/examples/providers/factory_init_injections_and_contexts.py b/examples/providers/factory_init_injections_and_contexts.py index 9058d5b0..da82d0b3 100644 --- a/examples/providers/factory_init_injections_and_contexts.py +++ b/examples/providers/factory_init_injections_and_contexts.py @@ -1,7 +1,6 @@ -"""`Factory` providers with init injections and context arguments example.""" +"""`di.Factory` providers with init injections priority example.""" -from dependency_injector.providers import Factory -from dependency_injector.injections import KwArg +import dependency_injector as di class User(object): @@ -34,11 +33,11 @@ class CreditCard(object): """Example class CreditCard.""" # User, Photo and CreditCard factories: -credit_cards_factory = Factory(CreditCard) -photos_factory = Factory(Photo) -users_factory = Factory(User, - KwArg('main_photo', photos_factory), - KwArg('credit_card', credit_cards_factory)) +credit_cards_factory = di.Factory(CreditCard) +photos_factory = di.Factory(Photo) +users_factory = di.Factory(User, + main_photo=photos_factory, + credit_card=credit_cards_factory) # Creating several User objects: user1 = users_factory(1) @@ -62,7 +61,7 @@ assert isinstance(user2.credit_card, CreditCard) assert user1.main_photo is not user2.main_photo assert user1.credit_card is not user2.credit_card -# Context keyword arguments have priority on KwArg injections priority: +# Context keyword arguments have priority on keyword argument injections: main_photo_mock = Photo() credit_card_mock = CreditCard()