diff --git a/Mirador_backend/app.py b/Mirador_backend/app.py
index 9ac4c9337c118174b9e3443e9829bf4235386cad..f8e1395dda723cbb842f2f9e49cc18c3f3844f69 100644
--- a/Mirador_backend/app.py
+++ b/Mirador_backend/app.py
@@ -4,25 +4,34 @@ from flask_restful_swagger import swagger
 from flask_apispec.extension import FlaskApiSpec
 
 from Mirador_backend.routes import v1
-from Mirador_backend.utils.config import ConfigFactory
+from Mirador_backend.utils.containers import Container
 from Mirador_backend.utils.database import db
-from Mirador_backend.utils.app import setApp
+from Mirador_backend.utils.config import Config
+from dependency_injector import providers
+from dependency_injector.wiring import Provide, inject
 
-app = Flask(__name__)
-setApp(app)
-api = Api(app)
-docs = FlaskApiSpec(app)
 
-app.config.from_object(ConfigFactory())
-app.db = db(app.config['DB'], app.config['DEBUG'])
+@inject
+def shutdown_session(db: db = Provide[Container.db], exception=None):
+    db.close()
 
-v1.register_routes(api, docs)
 
+@inject
+def do_create_app(config: Config = Provide[Container.config]) -> Flask:
+    app = Flask(__name__)
+    app.container = Container()
+    app.config = config
+    app.teardown_appcontext(shutdown_session)
+    api = Api(app)
+    docs = FlaskApiSpec(app)
+    v1.register_routes(api, docs)
+    return app
 
-@app.teardown_appcontext
-def shutdown_session(exception=None):
-    app.db.close()
+
+# Just for flask resolver
+def create_app():
+    return do_create_app()
 
 
 if __name__ == '__main__':
-    app.run()
+    create_app().run()
diff --git a/Mirador_backend/models.py b/Mirador_backend/models.py
index e6e15a9c64e07f3ecf7e17309fac7dee326b03f2..260868d1e31692b8aa9ceb49b1d529ffdd100d39 100644
--- a/Mirador_backend/models.py
+++ b/Mirador_backend/models.py
@@ -4,8 +4,10 @@ from sqlalchemy.orm import mapped_column
 from sqlalchemy import Integer, JSON
 from sqlalchemy import select
 from sqlalchemy.exc import NoResultFound
+from Mirador_backend.utils.containers import Container
+from Mirador_backend.utils.database import db
+from dependency_injector.wiring import Provide, inject
 import json
-from Mirador_backend.utils.app import getApp
 
 
 class NotFound(NoResultFound):
@@ -16,10 +18,10 @@ class BaseModel(DeclarativeBase):
     """A generic model class
     """
 
-    session = getApp().db.session
+    session = None
     """Access the db session"""
 
-    engine = getApp().db.engine
+    engine = None
     """Access the db session"""
 
     fillable = ['id']
@@ -33,13 +35,21 @@ class BaseModel(DeclarativeBase):
               }
     """Actual data fields"""
 
-    def create_all():
+    @inject
+    def __init__(self, db: db = Provide[Container.db]):
+        super().__init__()
+        if db is None:
+            raise Exception('DB must be set')
+        self.session = db.session
+        self.engine = db.engine
+
+    def create_all(self):
         """Creates all tables for all models"""
-        BaseModel.metadata.create_all(getApp().db.engine)
+        BaseModel.metadata.create_all(self.engine)
 
     def drop_all():
         """drop all tables for all models"""
-        BaseModel.metadata.drop_all(getApp().db.engine)
+        BaseModel.metadata.drop_all(self.engine)
 
     @classmethod
     def query(cls, stmt):
diff --git a/Mirador_backend/resources/base.py b/Mirador_backend/resources/base.py
index e264ec229954b9ebb6ee29d06042912c10696dc6..945ceae68b684b5ecebebf75e57c2b5296c41b0b 100644
--- a/Mirador_backend/resources/base.py
+++ b/Mirador_backend/resources/base.py
@@ -10,9 +10,6 @@ from flask_apispec import doc
 from flask_restful import marshal, fields
 
 from Mirador_backend.models import BaseModel, NotFound
-from Mirador_backend.utils.app import getApp
-
-logger = getApp().logger
 
 
 class ResourceGroup(MethodResource, Resource):
diff --git a/Mirador_backend/tests/tester.py b/Mirador_backend/tests/tester.py
index f2f6882b1c3e08cdf8e51d7bfef6a0d7da001298..2a1d61a16b0540340001cb4b5bc3bf4200e1ae85 100644
--- a/Mirador_backend/tests/tester.py
+++ b/Mirador_backend/tests/tester.py
@@ -3,14 +3,15 @@ import json
 from os.path import dirname, abspath
 from flask_fixtures import FixturesMixin
 
-from Mirador_backend.app import app
+from Mirador_backend.app import create_app
 from Mirador_backend.models import BaseModel
 
 
 class TestCase(unittest.TestCase, FixturesMixin):
     fixtures = ['test.json']
-    app = app
-    db = BaseModel
+
+    app = create_app()
+    db = BaseModel()
 
     def setUp(self):
         self.base = 'v1/mirador_resource'
diff --git a/Mirador_backend/utils/app.py b/Mirador_backend/utils/app.py
deleted file mode 100644
index 71f6b56ec5782e1acf0afb0376b8cb088d70f74b..0000000000000000000000000000000000000000
--- a/Mirador_backend/utils/app.py
+++ /dev/null
@@ -1,9 +0,0 @@
-def getApp():
-    return getApp.app
-
-
-getApp.app = None
-
-
-def setApp(app):
-    getApp.app = app
diff --git a/Mirador_backend/utils/config.py b/Mirador_backend/utils/config.py
index 002af568656fde59a17a71b24f981e74ee97f8fe..23e4297359b202ca3e339cc6833433c2dc98662f 100644
--- a/Mirador_backend/utils/config.py
+++ b/Mirador_backend/utils/config.py
@@ -23,13 +23,9 @@ class Config(object):
         'BASE': getenv('MYSQL_DATABASE', 'base'),
     }
 
-
-class TestingConfig(Config):
-    TESTING = True
-    DEBUG = True
-    DB = None
-    FIXTURES_DIRS = ['tests/fixtures']
-
-
-def ConfigFactory():
-    return TestingConfig if getenv('ENV', 'dev') == 'test' else Config
+    def __init__():
+        if getenv('ENV', 'dev') == 'test':
+            self.TESTING = True
+            self.DEBUG = True
+            self.DB = None
+            self.FIXTURES_DIRS = ['tests/fixtures']
diff --git a/Mirador_backend/utils/containers.py b/Mirador_backend/utils/containers.py
new file mode 100644
index 0000000000000000000000000000000000000000..624b4218456ef424dd40814237b17c46663fce02
--- /dev/null
+++ b/Mirador_backend/utils/containers.py
@@ -0,0 +1,14 @@
+from dependency_injector import containers, providers
+from Mirador_backend.utils.config import Config
+from Mirador_backend.utils.database import db
+
+
+class Container(containers.DeclarativeContainer):
+    wiring_config = containers.WiringConfiguration(modules=[
+        "Mirador_backend.app",
+        "Mirador_backend.models",
+        "Mirador_backend.resources.base",
+        "Mirador_backend.tests.tester"
+    ])
+    config = providers.Factory(Config)
+    db = providers.Factory(db, config=config)
diff --git a/Mirador_backend/utils/database.py b/Mirador_backend/utils/database.py
index 8d35a0d9336999665dea11abc82a34d1e10736dc..5f7c4ee8c44405860e4425affad25b904c429f4d 100644
--- a/Mirador_backend/utils/database.py
+++ b/Mirador_backend/utils/database.py
@@ -9,9 +9,9 @@ class db():
             return 'sqlite://'
         return f'{params["TYPE"]}://{params["USER"]}:{params["PASSWORD"]}@{params["HOST"]}/{params["BASE"]}'
 
-    def __init__(self, config, debug):
-        self.config = config
-        self.engine = create_engine(self.__getDBUri(), echo=debug)
+    def __init__(self, config):
+        self.config = config['DB']
+        self.engine = create_engine(self.__getDBUri(), echo=config['DEBUG'])
         self.session = scoped_session(sessionmaker(autocommit=False,
                                                    autoflush=False,
                                                    bind=self.engine))
diff --git a/setup.py b/setup.py
index 5cfd0c114c7824e806643ad1a615e1db4f3384cb..c9398281940281515420f9ef0e28d68291bb22e1 100644
--- a/setup.py
+++ b/setup.py
@@ -39,6 +39,7 @@ setup(
         # 1.1.x is incompatible with mariadb connector already in python:3.10 docker image
         "mariadb>=1.0.11,<1.1.0",
         "python-dotenv",
+        "dependency-injector",
     ],
 
     extras_require={