{ "info": { "author": "Felix Carmona", "author_email": "mail@felixcarmona.com", "bugtrack_url": null, "classifiers": [], "description": "Python Dependency Injection Container\n=====================================\n\n.. image:: https://travis-ci.org/felixcarmona/pydic.png?branch=master\n :target: https://travis-ci.org/felixcarmona/pydic\n\n.. image:: https://coveralls.io/repos/felixcarmona/pydic/badge.png?branch=master\n :target: https://coveralls.io/r/felixcarmona/pydic?branch=master\n\n.. image:: https://pypip.in/d/pydic/badge.png\n :target: https://pypi.python.org/pypi/pydic/\n :alt: Downloads\n\n.. image:: https://pypip.in/v/pydic/badge.png\n :target: https://pypi.python.org/pypi/pydic/\n :alt: Latest Version\n\nParameters\n----------\nThe ``pydic.Parameters`` class is a simple container for key/value pairs.\n\nThe available methods are:\n\n- ``set(key, value)``: Sets a parameter.\n- ``get(key, default=None)``: Returns a parameter by name. If the key don't exists, the default parameter will be returned.\n- ``has(key)``: Returns *True* if the parameter exists, *False* otherwise.\n- ``remove(key)``: Removes a parameter.\n- ``add(parameters)``: Adds a dict of parameters\n- ``all()``: Returns all set parameters.\n- ``count()``: Returns the number of all set parameters.\n- ``keys()``: Returns the all set parameter keys.\n- ``parse_text(text)``: Resolves a string which can contain parameters (example: 'Hello {{ name }} {{ surname }}!')\n\n\n.. note::\n\n You can reference others parameters wrapping it between ``{{`` ``}}`` characters.\n\n For example: ``'foo': '{{ bar }}', 'bar': 'aaa'``, if you get the ``foo`` parameter, the return value should be ``aaa`` because ``foo -> {{ bar }} -> bar -> aaa``\n\n You can escape brackets processing with \"``\\``\".\n\n For example, if you set a parameter with the following value ``Hello \\{\\{ name \\}\\}``, if you get it, the return will be ``Hello {{ name }}!``\n\n\nServices\n--------\n\nWhat is a Service Container\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\nA Service Container (or *dependency injection container*) is simply a python object that manages the instantiation of services (objects).\nFor example, suppose you have a simple python class that delivers email messages. Without a service container, you must manually create the object whenever you need it:\n\n.. code-block:: python\n\n from myapplication.mailer import Mailer\n\n mailer = Mailer('sendmail')\n mailer.send('felix@example.com', ...)\n\nThis is easy enough. The imaginary *Mailer* class allows you to configure the method used to deliver the\nemail messages (e.g. *sendmail*, *smtp*, etc).\n\nBut what if you wanted to use the mailer service somewhere else? You certainly don't want to repeat the mailer\nconfiguration every time you need to use the Mailer object. What if you needed to change the *transport* from *sendmail*\nto *smtp* everywhere in the application? You'd need to hunt down every place you create a *Mailer* service and change it.\n\nThe Services container allows you to standardize and centralize the way objects are constructed in your application.\n\nCreating/Configuring Services in the Container\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA better answer is to let the service container create the *Mailer* object for you.\nIn order for this to work, you must teach the container how to create the *Mailer* service.\nThis is done via configuration definitions:\n\n.. code-block:: python\n\n ...\n from pydic import Services\n\n definitions = {\n 'my_mailer': {\n 'class': 'myapplication.mailer.Mailer',\n 'arguments': ['sendmail']\n }\n }\n\n services = Services(definitions)\n ...\n\n\nWhen you ask for the *my_mailer* service from the container ``services.get('my_mailer')``, the container constructs the object and returns it.\n\nThis is another major advantage of using the service container. Namely, a service is never constructed until it's needed.\nIf you define a service and never use it, the service is never created. This saves memory and increases\nthe speed of your application. This also means that there's very little or no performance hit for defining lots\nof services. **Services that are never used are never constructed.**\n\nAs an added bonus, the *Mailer* service is only created once and the same instance is returned each time you ask for\nthe service. This is almost always the behavior you'll need (it's more flexible and powerful).\n\nYou can pass the arguments as list or dict.\n\nAlso you can call functions after object instantiation with:\n\n.. code-block:: python\n\n ...\n definitions = {\n 'my_mailer': {\n 'class': 'myapplication.mailer.Mailer',\n 'arguments': ['sendmail'],\n 'calls': [\n [ 'set_name', 'Felix Carmona'],\n [ 'inject_something', [1, 2, 3]],\n [ 'inject_something', [2, 3]],\n [ 'set_location', {'city': 'Barcelona', 'country': 'Spain'}]\n ]\n }\n }\n ...\n\n\nOnce the container has been constructed with the definitions, the available methods for the service container object are:\n\n- ``set(key, value)``: Sets a service object by name.\n- ``get(key)``: Returns a service object by name.\n- ``has(key)``: Returns *True* if the service definition exists or if the service object is instantiated, *False* otherwise.\n- ``remove(key)``: Removes a service object and service definition by name.\n- ``add(parameters)``: Adds a dict of services objects.\n- ``keys()``: Returns the services keys.\n\n\nUsing the Parameters to build Services\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThe creation of new services (objects) via the container is pretty straightforward. Parameters make defining services\nmore organized and flexible:\n\n.. code-block:: python\n\n ...\n parameters = Parameters(\n {\n 'my_mailer_class': 'myapplication.mailer.Mailer',\n 'my_mailer_transport': 'sendmail'\n }\n )\n\n definitions = {\n 'my_mailer': {\n 'class': '{{ my_mailer_class }}',\n 'arguments': ['{{ my_mailer_transport }}']\n }\n }\n\n services = Services(definitions, parameters)\n ...\n\n\nThe end result is exactly the same as before - the difference is only in how you defined the service.\nBy surrounding the *my_mailer.class* and *my_mailer.transport* strings in double bracket keys (``{{`` ``}}``) signs, the services container knows to look\nfor parameters with those names. Parameters can deep reference other parameters that references other parameters, and will\nbe resolved anyway.\n\nThe purpose of parameters is to feed information into services. Of course there was nothing wrong with defining the\nservice without using any parameters. Parameters, however, have several advantages:\n\n - separation and organization of all service \"options\" under a single parameters key\n - parameter values can be used in multiple service definitions\n\nThe choice of using or not using parameters is up to you.\n\n\nReferencing (Injecting) Services\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can of course also reference services\n\nStart the string with @ to reference a service, example:\n\n.. code-block:: python\n\n ...\n parameters = Parameters(\n {\n 'my_mailer_class': 'myapplication.mailer.Mailer',\n 'my_mailer_transport': 'sendmail'\n }\n )\n\n definitions = {\n 'my_mailer': {\n 'class': '{{ my_mailer_class }}',\n 'arguments': ['{{ my_mailer_transport }}']\n },\n 'my_mailer_manager': {}\n 'class': 'myapplication.mailer.MailerManager',\n 'arguments': ['@my_mailer']\n }\n }\n\n services = Services(definitions, parameters)\n ...\n\n\nthe *my_mailer* service will be injected in the *my_mailer_manager*\n\n.. note::\n\n Use ``@@`` to escape the ``@`` symbol. ``@@my_mailer`` will be converted into the string \"``@my_mailer``\" instead of referencing the\n *my_mailer* service.\n\n------------------\n\n*pydic is open-sourced software licensed under the MIT license*", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/felixcarmona/pydic", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "pydic", "package_url": "https://pypi.org/project/pydic/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/pydic/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/felixcarmona/pydic" }, "release_url": "https://pypi.org/project/pydic/1.0.0/", "requires_dist": null, "requires_python": null, "summary": "Manage your services via a robust and flexible Dependency Injection Container", "version": "1.0.0" }, "last_serial": 1275252, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "e790d10448ed6e6a8729a1ca79e650d2", "sha256": "2f9e8e2dd59cd9e80f0fd06df77c54f315209568b848f592d3ca6552e837ef55" }, "downloads": -1, "filename": "pydic-1.0.0.tar.gz", "has_sig": false, "md5_digest": "e790d10448ed6e6a8729a1ca79e650d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5833, "upload_time": "2014-10-18T21:41:32", "url": "https://files.pythonhosted.org/packages/4e/96/287792fc63d5cd631e85572aa5511a2fbde7319d1808f91790f36552270e/pydic-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e790d10448ed6e6a8729a1ca79e650d2", "sha256": "2f9e8e2dd59cd9e80f0fd06df77c54f315209568b848f592d3ca6552e837ef55" }, "downloads": -1, "filename": "pydic-1.0.0.tar.gz", "has_sig": false, "md5_digest": "e790d10448ed6e6a8729a1ca79e650d2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5833, "upload_time": "2014-10-18T21:41:32", "url": "https://files.pythonhosted.org/packages/4e/96/287792fc63d5cd631e85572aa5511a2fbde7319d1808f91790f36552270e/pydic-1.0.0.tar.gz" } ] }