Inject is recommended for DDD in Python

Overview

It's a bit old article, but InfoQ's Domain Driven Design and Development Practices says:

The design dependency that the domain class depends on the Data Access Object (DAO) class and the service class depends on the domain class must "DI" for implementation by DDD. "I'm making it.

For Python, Inject is useful for achieving DI (Dependency Injection).

Usage example

If you write a sample with roughly 100 lines, it will look like this.

# -*- coding: utf-8 -*-
import uuid
from abc import ABCMeta, abstractmethod

import inject


def config(binder):
    binder.bind(UserRepository, UserMemoryRepository())


class User(object):

    def __init__(self, identity, name):
        self.identity = identity
        self.name = name


class UserRepository(object):
    u""" Base class of User Repository"""
    __metaclass__ = ABCMeta

    @abstractmethod
    def store(self, user):
        raise NotImplementedError

    @abstractmethod
    def find_by_identity(self, identity):
        raise NotImplementedError


class UserMemoryRepository(UserRepository):
    u""" User Repository on memory"""

    def __init__(self):
        self._users = {}

    def store(self, user):
        if not isinstance(user, User):
            raise TypeError
        self._users[user.identity] = user

    def find_by_identity(self, identity):
        return self._users[identity]


class UserRedisRepository(UserRepository):
    u""" User Repository on Redis """

    def store(self, user):
        # TODO: write code here
        pass

    def find_by_identity(self, identity):
        # TODO: write code here
        pass


class UserService(object):
    u""" User Service on Application Layer"""
    repo = inject.attr(UserRepository)

    def create_user(self, name):
        user = User(uuid.uuid4(), name)
        self.repo.store(user)
        return user

    def find_by_identity(self, identity):
        return self.repo.find_by_identity(identity)


if __name__ == "__main__":
    # Call once on application start
    inject.configure(config)

    user_service = UserService()
    created_user = user_service.create_user('foo')
    stored_user = user_service.find_by_identity(created_user.identity)

    assert created_user == stored_user

To achieve the same thing without using ʻinject, you need to pass repo as an argument to ʻUserService, which makes the constructor of ʻUserService bloated as the number of dependencies increases. , ʻInject can be used to write clearly. You can also use the @ inject.params decorator to inject dependencies into the default arguments of the constructor.

It's a small library with only 300 lines, but it's very useful.

Recommended Posts

Inject is recommended for DDD in Python
Search for strings in Python
Techniques for sorting in Python
About "for _ in range ():" in python
What is Python? What is it used for?
Check for memory leaks in Python
Check for external commands in python
Difference between == and is in python
Use fabric as is in python (fabric3)
Python is UnicodeEncodeError in CodeBox docker
Python for statement ~ What is iterable ~
Recommended container image for Python applications
There is no switch in python
What is the python underscore (_) for?
Run unittests in Python (for beginners)
Python in is also an operator
Notes on nfc.ContactlessFrontend () for nfcpy in python
Tips for dealing with binaries in Python
Why Python is chosen for machine learning
Summary of various for statements in Python
Type annotations for Python2 in stub files!
Template for writing batch scripts in python
What is "mahjong" in the Python library? ??
Hash in Perl is a dictionary in Python
Process multiple lists with for in Python
MongoDB for the first time in Python
Get a token for conoha in python
Sample for handling eml files in Python
AtCoder cheat sheet in python (for myself)
I searched for prime numbers in python
Notes for using python (pydev) in eclipse
Tips for making small tools in python
Use pathlib in Maya (Python 2.7) for upcoming Python 3.7
How to use is and == in Python
[Example of Python improvement] What is the recommended learning site for Python beginners?
2016-10-30 else for Python3> for:
Template for creating command line applications in Python
Quadtree in Python --2
Python in optimization
python [for myself]
CURL in python
CERTIFICATE_VERIFY_FAILED in Python 3.6, the official installer for macOS
Metaprogramming in Python
++ and-cannot be used for increment / decrement in python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Python is easy
Python Pandas is not suitable for batch processing
Meta-analysis in Python
Unittest in python
Import-linter was useful for layered architecture in Python
Tips for those who are wondering how to use is and == in Python
For new students (Recommended efforts for Python beginners Part 1)
What is wheezy in the Docker Python image?
Wagtail is the best CMS for Python! (Perhaps)
Epoch in Python
Discord in Python
Add quotation marks ">" for replying emails in Python3
Sudoku in Python
DCI in Python