I’ve several repositories. To make them testable, I add the ORM session in the constructor.

class Repository:
  def __init__(session):
    self.session = session

  def save(object):

class FruitRepository(Repository):
  def custom_method():
   # ...

Problem: I need to inject the session every time I instantiate a repository. I’d like to have only one place in my code where the injection happens.

To clean things up I’d like to separate creation from usage:

from db import session

def create_fruit_repository():
  return FruitRepository(session)

repository = create_fruit_repository()

It doesn’t feel clean. Does anyone know a proper pattern to solve this issue? Maybe the factory pattern?

Further information: the application is a web scraper with several layers (loading, processing, analysing, reporting). It has some dependencies, but no framework. The application runs constantly as a services, not as a cronjob. Most is done on the command line, but it provides a REST-API.



CLI or API both are likely to have an entry point. The so-called Main or Application.

Sometimes, it’s a class and sometimes is a function. In some programming languages is a mix of both. In any case, this entry point is the best place for your Composition Root. It’s the epicentre of your dependency graph explosion. Where you instantiate everything and pass it downstream.

CLI apps are kinda fire and forget executables. The Main builds a new graph every time. Dependencies are created and passed downstream up to the end of the execution path. Then, the execution and the Main end.

Endless loops applications are a bit different. The Composition Root is not enough. It builds the graph once and it must be accessible and executable anytime (for efficiency). It’s then when we need a place to store (in memory) the graph and a way to access it. The link I shared (see comments above) mentions the Service Registry pattern. Frameworks might have other names: ApplictionContext, Container, etc…

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *