From b86760e46798c6b6b251fa5cf737750b8fed6f02 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Fri, 3 Jun 2016 00:48:06 +0300 Subject: [PATCH] Make huge updates for docs (not atomic commit) --- docs/api/catalogs.rst | 6 -- docs/api/containers.rst | 6 ++ docs/api/index.rst | 3 +- docs/api/injections.rst | 6 -- docs/catalogs/declarative.rst | 64 ------------------ docs/catalogs/index.rst | 27 -------- docs/containers/declarative.rst | 55 +++++++++++++++ docs/{catalogs => containers}/dynamic.rst | 2 +- docs/containers/index.rst | 28 ++++++++ docs/{catalogs => containers}/overriding.rst | 2 +- .../specialization.rst | 2 +- docs/images/internals.png | Bin 29767 -> 8378 bytes docs/index.rst | 2 +- docs/introduction/di_in_python.rst | 4 +- docs/introduction/structure.rst | 38 +++++------ docs/main/changelog.rst | 3 +- docs/main/installation.rst | 6 +- 17 files changed, 118 insertions(+), 136 deletions(-) delete mode 100644 docs/api/catalogs.rst create mode 100644 docs/api/containers.rst delete mode 100644 docs/api/injections.rst delete mode 100644 docs/catalogs/declarative.rst delete mode 100644 docs/catalogs/index.rst create mode 100644 docs/containers/declarative.rst rename docs/{catalogs => containers}/dynamic.rst (95%) create mode 100644 docs/containers/index.rst rename docs/{catalogs => containers}/overriding.rst (97%) rename docs/{catalogs => containers}/specialization.rst (96%) diff --git a/docs/api/catalogs.rst b/docs/api/catalogs.rst deleted file mode 100644 index 08cdfef9..00000000 --- a/docs/api/catalogs.rst +++ /dev/null @@ -1,6 +0,0 @@ -``dependency_injector.catalogs`` --------------------------------- - -.. automodule:: dependency_injector.catalogs - :members: - :special-members: diff --git a/docs/api/containers.rst b/docs/api/containers.rst new file mode 100644 index 00000000..79678008 --- /dev/null +++ b/docs/api/containers.rst @@ -0,0 +1,6 @@ +``dependency_injector.containers`` +-------------------------------- + +.. automodule:: dependency_injector.containers + :members: + :special-members: diff --git a/docs/api/index.rst b/docs/api/index.rst index 6d767939..1f1df940 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -6,7 +6,6 @@ API Documentation top_level providers - injections - catalogs + containers utils errors diff --git a/docs/api/injections.rst b/docs/api/injections.rst deleted file mode 100644 index 71884fe7..00000000 --- a/docs/api/injections.rst +++ /dev/null @@ -1,6 +0,0 @@ -``dependency_injector.injections`` ----------------------------------- - -.. automodule:: dependency_injector.injections - :members: - :inherited-members: diff --git a/docs/catalogs/declarative.rst b/docs/catalogs/declarative.rst deleted file mode 100644 index fbe241ea..00000000 --- a/docs/catalogs/declarative.rst +++ /dev/null @@ -1,64 +0,0 @@ -Declarative catalogs --------------------- - -.. currentmodule:: dependency_injector.catalogs - -:py:class:`DeclarativeCatalog` is a catalog of providers that could be -defined in declarative manner. It should cover most of the cases when list -of providers that would be included in catalog is deterministic (catalog -will not change its structure in runtime). - -Declarative catalogs have to extend base declarative catalog class - -:py:class:`dependency_injector.catalogs.DeclarativeCatalog`. - -Declarative catalog's providers have to be defined like catalog's class -attributes. Every provider in catalog has name. This name should follow -``some_provider`` convention, that is standard naming convention for -attribute names in Python. - -.. note:: - - Declarative catalogs have several features that could be useful - for some kind of operations on catalog's providers, please visit API - documentation for getting full list of features - - :py:class:`dependency_injector.catalogs.DeclarativeCatalog`. - -.. note:: - - It might be useful to add such - ``""":type: dependency_injector.providers.Provider -> Object1"""`` - docstrings just on the next line after provider's definition. It will - help code analyzing tools and IDE's to understand that variable above - contains some callable object, that returns particular instance as a - result of its call. - -Here is an simple example of defining declarative catalog with several -factories: - -.. image:: /images/catalogs/declarative.png - :width: 85% - :align: center - -.. literalinclude:: ../../examples/catalogs/declarative.py - :language: python - :linenos: - -Example of declarative catalogs inheritance: - -.. image:: /images/catalogs/declarative_inheritance.png - :width: 100% - :align: center - -.. literalinclude:: ../../examples/catalogs/declarative_inheritance.py - :language: python - :linenos: - -Example of declarative catalog's provider injections: - -.. image:: /images/catalogs/declarative_injections.png - :width: 100% - :align: center - -.. literalinclude:: ../../examples/catalogs/declarative_injections.py - :language: python - :linenos: diff --git a/docs/catalogs/index.rst b/docs/catalogs/index.rst deleted file mode 100644 index fa4e4ca8..00000000 --- a/docs/catalogs/index.rst +++ /dev/null @@ -1,27 +0,0 @@ -Catalogs -======== - -Catalogs are collections of providers. Main purpose of catalogs is to group -providers. - -There are, actually, several popular cases of catalogs usage: - -- Grouping of providers from the same architectural layer (for example, - ``Services``, ``Models`` and ``Forms`` catalogs). -- Grouping of providers from the same functional groups (for example, - catalog ``Users``, that contains all functional parts of ``Users`` - component). - -Also, for both of these and some other cases, it might be useful to attach -some init / shutdown functionality or something else, that deals with group -of providers. - -Catalogs module API docs - :py:mod:`dependency_injector.catalogs`. - -.. toctree:: - :maxdepth: 2 - - declarative - dynamic - specialization - overriding diff --git a/docs/containers/declarative.rst b/docs/containers/declarative.rst new file mode 100644 index 00000000..e290251e --- /dev/null +++ b/docs/containers/declarative.rst @@ -0,0 +1,55 @@ +Declarative containers +-------------------- + +.. currentmodule:: dependency_injector.containers + +:py:class:`DeclarativeContainer` is a container of providers that could be +defined in declarative manner. It should cover most of the cases when list +of providers that would be included in container is deterministic (container +will not change its structure in runtime). + +Declarative containers have to extend base declarative container class - +:py:class:`dependency_injector.containers.DeclarativeContainer`. + +Declarative container's providers have to be defined like container's class +attributes. Every provider in container has name. This name should follow +``some_provider`` convention, that is standard naming convention for +attribute names in Python. + +.. note:: + + Declarative containers have several features that could be useful + for some kind of operations on container's providers, please visit API + documentation for getting full list of features - + :py:class:`dependency_injector.containers.DeclarativeContainer`. + +Here is an simple example of defining declarative container with several +factories: + +.. image:: /images/containers/declarative.png + :width: 85% + :align: center + +.. literalinclude:: ../../examples/containers/declarative.py + :language: python + :linenos: + +Example of declarative containers inheritance: + +.. image:: /images/containers/declarative_inheritance.png + :width: 100% + :align: center + +.. literalinclude:: ../../examples/containers/declarative_inheritance.py + :language: python + :linenos: + +Example of declarative containers's provider injections: + +.. image:: /images/containers/declarative_injections.png + :width: 100% + :align: center + +.. literalinclude:: ../../examples/containers/declarative_injections.py + :language: python + :linenos: diff --git a/docs/catalogs/dynamic.rst b/docs/containers/dynamic.rst similarity index 95% rename from docs/catalogs/dynamic.rst rename to docs/containers/dynamic.rst index 8489b60f..773dd20b 100644 --- a/docs/catalogs/dynamic.rst +++ b/docs/containers/dynamic.rst @@ -1,7 +1,7 @@ Dynamic catalogs ---------------- -.. currentmodule:: dependency_injector.catalogs +.. currentmodule:: dependency_injector.containers :py:class:`DynamicCatalog` is a catalog of providers that could be created in application's runtime. It should cover most of the cases when list of diff --git a/docs/containers/index.rst b/docs/containers/index.rst new file mode 100644 index 00000000..0cd66a08 --- /dev/null +++ b/docs/containers/index.rst @@ -0,0 +1,28 @@ +Containers +========== + +Containers are collections of providers. Main purpose of containers is to group +providers. + +There are, actually, several popular cases of containers usage: + ++ Keeping all providers in a single container. ++ Grouping of providers from the same architectural layer (for example, + ``Services``, ``Models`` and ``Forms`` containers). ++ Grouping of providers from the same functional groups (for example, + container ``Users``, that contains all functional parts of ``Users`` + component). + +Also, for both of these and some other cases, it might be useful to attach +some init / shutdown functionality or something else, that deals with group +of providers. + +Containers module API docs - :py:mod:`dependency_injector.containers`. + +.. toctree:: + :maxdepth: 2 + + declarative + dynamic + specialization + overriding diff --git a/docs/catalogs/overriding.rst b/docs/containers/overriding.rst similarity index 97% rename from docs/catalogs/overriding.rst rename to docs/containers/overriding.rst index b94ffa7e..676810c2 100644 --- a/docs/catalogs/overriding.rst +++ b/docs/containers/overriding.rst @@ -1,7 +1,7 @@ Overriding of catalogs ---------------------- -.. currentmodule:: dependency_injector.catalogs +.. currentmodule:: dependency_injector.containers Catalogs can be overridden by other catalogs. This, actually, means that all of the providers from overriding catalog will override providers with the diff --git a/docs/catalogs/specialization.rst b/docs/containers/specialization.rst similarity index 96% rename from docs/catalogs/specialization.rst rename to docs/containers/specialization.rst index 0bd622e3..1647180a 100644 --- a/docs/catalogs/specialization.rst +++ b/docs/containers/specialization.rst @@ -1,7 +1,7 @@ Specialization of catalogs -------------------------- -.. currentmodule:: dependency_injector.catalogs +.. currentmodule:: dependency_injector.containers :py:class:`DeclarativeCatalog` and :py:class:`DynamicCatalog` could be specialized for any kind of needs via declaring its subclasses. diff --git a/docs/images/internals.png b/docs/images/internals.png index bd91b3f5549965a31887fda21a4ec54d0cd70ba5..35b99dcbbc45888b98378c3da9f8808bc8a004ef 100644 GIT binary patch literal 8378 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 IE$5g21sW@{h5!Hn diff --git a/docs/index.rst b/docs/index.rst index 267aa8a8..7eefdb52 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -58,7 +58,7 @@ Contents introduction/index main/installation providers/index - catalogs/index + containers/index advanced_usage/index examples/index api/index diff --git a/docs/introduction/di_in_python.rst b/docs/introduction/di_in_python.rst index 378c9ccf..8411403f 100644 --- a/docs/introduction/di_in_python.rst +++ b/docs/introduction/di_in_python.rst @@ -119,9 +119,9 @@ Let's automate ``Engine`` into ``Car`` injections using *Dependency Injector*: .. note:: - ``Components`` from previous example is an inversion of control container. + ``Container`` from previous example is an inversion of control container. It contains a collection of component providers that could be injected into each other. - Assuming this, ``Components`` could be one and the only place, where + Assuming this, ``Container`` could be one and the only place, where application's structure is being managed on the high level. diff --git a/docs/introduction/structure.rst b/docs/introduction/structure.rst index b2a5391a..54f8d4d9 100644 --- a/docs/introduction/structure.rst +++ b/docs/introduction/structure.rst @@ -5,8 +5,8 @@ Structure of Dependency Injector :keywords: Python,DI,Dependency injection,IoC,Inversion of Control :description: This article describes "Dependency Injector" framework components and their interaction between each other. - Catalogs, providers and injections are the former - components of the framework. + Providers and containers are the former components of + the framework. Current section describes *Dependency Injector* main entities and their interaction between each other. @@ -15,11 +15,7 @@ interaction between each other. :width: 100% :align: center -There are 3 main entities: providers, injections and catalogs. - -+ All of the entities could be used in composition with each other or - separatelly. -+ Each of the entities could be extended via specialization. +There are 3 main entities: providers, containers. Providers ~~~~~~~~~ @@ -33,19 +29,21 @@ injected into each other. Providers could be overridden by another providers. Base class is - :py:class:`dependency_injector.providers.Provider`. -Injections +Providers could be: + ++ Injected into each other. ++ Overridden by each other. ++ Extended. + +Containers ~~~~~~~~~~ -Injections are instructions for making dependency injections -(there are several ways how they could be done). Injections are used -mostly by :py:class:`dependency_injector.providers.Factory` and -:py:class:`dependency_injector.providers.Singleton` providers, but -these are not only cases. Base class is - -:py:class:`dependency_injector.injections.Injection`. - -Catalogs -~~~~~~~~~ - -Catalogs are collections of providers. They are used for grouping +Containers are collections of providers. They are used for grouping of providers by some principles. Base class is - -:py:class:`dependency_injector.catalogs.DeclarativeCatalog`. +:py:class:`dependency_injector.containers.DeclarativeContainer`. + +Containers could be: + ++ Overridden by each other. ++ Copied from each other. ++ Extended. diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 2ace8601..1a81bb25 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -23,8 +23,7 @@ Development version - ``Class`` - ``Config`` - Drop method injections. -- Drop catalog bundles. -- Drop catalog's ``name`` attribute. +- Replace catalogs with containers. - Drop backward compatibilities of 1.x. 1.17.0 diff --git a/docs/main/installation.rst b/docs/main/installation.rst index 1422383b..1a3e0cd1 100644 --- a/docs/main/installation.rst +++ b/docs/main/installation.rst @@ -12,13 +12,13 @@ framework can be installed from PyPi_: pip install dependency_injector # Installing particular version: - pip install dependency_injector==0.11.0 + pip install dependency_injector==2.0.0 Sources can be cloned from GitHub_: .. code-block:: bash - git clone https://github.com/ets-labs/dependency_injector.git + git clone https://github.com/ets-labs/python-dependency-injector.git Also all *Dependency Injector* releases can be downloaded from `GitHub releases page`_. @@ -30,7 +30,7 @@ Verification of currently installed version could be done using >>> from dependency_injector import VERSION >>> VERSION - '0.11.0' + '2.0.0' .. _PyPi: https://pypi.python.org/pypi/dependency_injector .. _GitHub: https://github.com/ets-labs/python-dependency-injector