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):
self.session().query(object).save()
class FruitRepository(Repository):
def custom_method():
# ...
pass
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?
Edit
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.
-
2Can you explain more about the program you are trying to create? The overall architecture of the application makes a big difference.Greg Burghardt– Greg Burghardt09/06/2022 12:12:38Commented Sep 6, 2022 at 12:12
-
@GregBurghardt Thanks for your reply. It's a more or less complex web scraper with several layers. It loads, processes, analyses and reports. Unfortunately I can't rely on an existing framework.Mr. B.– Mr. B.09/06/2022 12:44:05Commented Sep 6, 2022 at 12:44
-
1This is good information. Please edit your question instead of commenting. It is too easy to miss this in comments. As for the web scraper, is this just a Python script started from a cron job or command line?Greg Burghardt– Greg Burghardt09/06/2022 12:54:27Commented Sep 6, 2022 at 12:54
-
@GregBurghardt Thanks, I just edited the question including the answer to your latest question.Mr. B.– Mr. B.09/06/2022 13:05:36Commented Sep 6, 2022 at 13:05
-
1Have you considered using a scraping framework such as Scrapy?WMRamadan– WMRamadan09/12/2022 01:22:40Commented Sep 12, 2022 at 1:22
1 Answer 1
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...
-
1An alternative to the service registry is to use factories. This enables parts of the graph to be lazily constructed on demand, potentially when needed, whilst still keeping the construction code in the composition root.user1937198– user193719802/04/2023 18:26:12Commented Feb 4, 2023 at 18:26
Explore related questions
See similar questions with these tags.