DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Securing Your Software Supply Chain with JFrog and Azure
Register Today

Trending

  • Understanding Dependencies...Visually!
  • How To Approach Java, Databases, and SQL [Video]
  • Competing Consumers With Spring Boot and Hazelcast
  • Microservices With Apache Camel and Quarkus (Part 2)

Trending

  • Understanding Dependencies...Visually!
  • How To Approach Java, Databases, and SQL [Video]
  • Competing Consumers With Spring Boot and Hazelcast
  • Microservices With Apache Camel and Quarkus (Part 2)
  1. DZone
  2. Coding
  3. Languages
  4. Dependency Injection: Python

Dependency Injection: Python

Dependency injection is just one of those things you need to know when you're a programmer. Read on to learn about DI and/or brush up on your skills.

Shivam Aggarwal user avatar by
Shivam Aggarwal
·
Jul. 24, 18 · Tutorial
Like (4)
Save
Tweet
Share
23.57K Views

Join the DZone community and get the full member experience.

Join For Free

Overview

Dependency Injection (DI) is a software engineering technique for defining the dependencies among objects. Basically, the process of supplying a resource that a given piece of code requires. The required resource is called a dependency.

There are various classes and objects defined when writing code. Most of the time, these classes depend on other classes in order to fulfill their intended purpose. These classes, or a better word might be Components, know the resources they need and how to get them. DI handles defining these dependent resources and provides ways to instantiate or create them externally. Dependency Containers are used to implement this behavior and holds the map of dependencies for the components.

If object A depends on object B, object A must not create or import object B directly. Instead, object A must provide a way for injecting object B. The responsibilities of object creation and dependency injection are delegated to external code.

Why Use Dependency Injection in Your Code?

  • The flexibility of configurable components: As the components are externally configured, there can be various definitions for a component (Control on application structure).
  • Testing Made Easy: Instantiating mock objects and integrating with class definitions is easier.
  • High cohesion: Code with reduced module complexity, increased module reusability.
  • Minimalistic dependencies: As the dependencies are clearly defined, easier to eliminate/reduce unnecessary dependencies.

Implementing DI in Python

Dependency Injection in Python is little different from general static language DI. Python has a microframework library for DI, called dependency_injector. This package has two main entities: containers and providers.

Providers describe how objects are accessed. Containers are simply a collection of providers. Most commonly used provider types are: Singleton, Configuration, and Factory.

Example

The following example demonstrates the usage and implementation of DI in Python. Create a file named email_client.py containing the EmailClient class which depends on the object.

class EmailClient(object):

    def __init__(self, config):
        self._config = config
        self.connect(self._config)

    def connect(self, config):
        # Implement function here
        pass

Create a new file named e mail_reader.py which contains the  EmailReader class and depends on the EmailClient object.

class EmailReader(object):

    def __init__(self, client):
        try:
            self._client = client
        except Exception as e:
            raise e

    def read(self):
        # Implement function here
        pass

Now to define these above dependencies externally, create a new containers.py file. Import the dependency_injector package and the classes to be used in DI.

from dependency_injector import providers, containers
from email_client import EmailClient
from email_reader import EmailReader

Add the class Configs to the file. This class is a container with a configuration provider which provides all the configuration objects.

class Configs(containers.DeclarativeContainer): 
  config = providers.Configuration('config') 
  # other configs

Add another class, Clients. This class is a container defining all kinds of clients. EmailClient is created with a singleton provider, asserting single instances of this class, and defining its dependency on an object.

class Clients(containers.DeclarativeContainer): 
  email_client = providers.Singleton(EmailClient, Configs.config) 
  # other clients 

The third container is the Readersclass, defining the dependency of EmailReader class on the EmailClient class.

class Readers(containers.DeclarativeContainer): 
  email_reader = providers.Factory(EmailReader, client=Clients.email_client) 
  # other readers 
from dependency_injector import providers, containers
from email_client import EmailClient
from email_reader import EmailReader

class Configs(containers.DeclarativeContainer):
    config = providers.Configuration('config')
    # other configs

class Clients(containers.DeclarativeContainer):
    email_client = providers.Singleton(EmailClient, Configs.config)
    # other clients

class Readers(containers.DeclarativeContainer):
    email_reader = providers.Factory(EmailReader, client=Clients.email_client)
    # other readers

To run the example, create the main.py file with following code.

from containers import Readers, Clients, Configs

if __name__ == "__main__":
    Configs.config.override({
        "domain_name": "imap.gmail.com",
        "email_address": "YOUR_EMAIL_ADDRESS",
        "password": "YOUR_PASSWORD",
        "mailbox": "INBOX"
    })
    email_reader = Readers.email_reader()
    print email_reader.read()

In the main.py file, the object is overridden with a given dictionary object. The EmailReader class was instantiated without instantiating the  EmailClient class in the main file, removing the overhead of importing or creating it. That part is taken care by containers file.

For a working example, please refer to my GitHub repo here.

Dependency injection Python (language) Object (computer science)

Published at DZone with permission of Shivam Aggarwal. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Understanding Dependencies...Visually!
  • How To Approach Java, Databases, and SQL [Video]
  • Competing Consumers With Spring Boot and Hazelcast
  • Microservices With Apache Camel and Quarkus (Part 2)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: