How do I handle dependency injection in Django?

Viewed 29

I am currently trying to manage dependency injection in a django application. I found this thread (Is this the right way to do dependency injection in Django?) and tried the following simple example based on what I found there.

/dependencyInjection/serviceInjector.py

from functools import wraps

class ServiceInjector:

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

    def register(self, name=None):

        name = name
        def decorator(thing):
            """
            thing here can be class or function or anything really
            """

            if not name:
                if not hasattr(thing, "__name__"): 
                    raise Exception("no name")
                thing_name = thing.__name__ #Set the name of the dependency to the name of the class
            else:
                thing_name = name   
            self.deps[thing_name] = thing 
            return thing

        return decorator

    def inject(self, func):

        @wraps(func)
        def decorated(*args, **kwargs):
            new_args = args + (self.deps, )
            return func(*new_args, **kwargs)

        return decorated

init.py

from backend.dependencyInjection.serviceInjector import ServiceInjector

si = ServiceInjector()

/core/articleModule.py

from backend.core.IarticleModule import IarticleModule
from models import Article
from backend.__init__ import si 

@si.register()
class articleModule(IarticleModule):
    def getArticleByLioId(self, lioId: str) -> Article:
        return Article.objects.get(lioId = lioId)

/services/articleManagementService.py

from backend.services.IarticleManagementService import IarticleManagementService
from backend.models import Article
from backend.__init__ import si 

@si.register()
class articleManagementService(IarticleManagementService):
    @si.inject
    def __init__(self, _deps):  
        articleModule = _deps['articleModule']
        self._articleModule = articleModule()

    def getArticleByLioId(self, lioId: str) -> Article:
        return self._articleModule.getArticleByLioId(lioId)

/views.py

from backend.__init__ import si

class article(View): 
    @si.inject
    def __init__(self, _deps):
        self._articleManagementService = _deps['articleManagementService']
    def get(self, request, articleId): 
        article = self._articleManagementService.getArticleByLioId(articleId)
        return article

When running this code i get the following error: articleManagementService.getArticleByLioId() missing 1 required positional argument: 'lioId'

It seems to me like the articleManagementService is getting an uninstantiated version of the articleModule class. Is there any way i could solve this in order to get this idea to work nicely?

Sorry for the long question, I tried to only include the necessary parts of the code.

0 Answers
Related