From ab26f594af4bf65f3923c573362417f83fc9ae8e Mon Sep 17 00:00:00 2001 From: tarsil Date: Tue, 3 Oct 2023 21:27:36 +0100 Subject: [PATCH] Add documentation about the Factory import --- docs/dependencies.md | 42 ++++++++++++++++++-- docs_src/dependencies/urls_factory_import.py | 18 +++++++++ mkdocs.yml | 2 +- 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 docs_src/dependencies/urls_factory_import.py diff --git a/docs/dependencies.md b/docs/dependencies.md index a3e06709..1c6093f6 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -49,7 +49,7 @@ and checks if the value is bigger or equal than 5 and that result `is_valid` is The same is applied also to [exception handlers](./exception-handlers.md). -## More Real World example +## More real world examples Now let us imagine that we have a web application with one of the views. Something like this: @@ -57,9 +57,9 @@ Now let us imagine that we have a web application with one of the views. Somethi {!> ../docs_src/dependencies/views.py !} ``` -As you can notice, the user_dao is injected automatically using the appropriate level of dependency injection.. +As you can notice, the `user_dao`` is injected automatically using the appropriate level of dependency injection. -Let's see the `urls.py` and understand from where we got the `user_dao`: +Let us see the `urls.py` and understand from where we got the `user_dao`: ```python hl_lines="14-16 32-34" {!> ../docs_src/dependencies/urls.py !} @@ -85,5 +85,41 @@ The Factory is a clean wrapper around any callable (classes usually are callable No need to explicitly instantiate the class, just pass the class definition to the `Factory` and Esmerald takes care of the rest for you. +### Importing using strings + +Like everything is Esmerald, there are different ways of achieving the same results and the `Factory` +is no exception. + +In the previous examples we were passing the `UserDAO`, `ArticleDAO` and `PostDAO` classes directly +into the `Factory` object and that also means that **you will need to import the objects to then be passed**. + +What can happen with this process? Majority of the times nothing **but** you can also have the classic +`partially imported ...` annoying error, right? + +Well, the good news is that Esmerald got you covered, as usual. + +The `Factory` **also allows import via string** without the need of importing directly the object +to the place where it is needed. + +Let us then see how it would look like and let us then assume: + +1. The `UserDAO` is located somewhere in the codebase like `myapp.accounts.daos`. +2. The `ArticleDAO` is located somewhere in the codebase like `myapp.articles.daos`. +3. The `PostDAO` is located somewhere in the codebase like `myapp.posts.daos`. + +Ok, now that we know this, let us see how it would look like in the codebase importing it inside the +`Factory`. + +```python hl_lines="13-15" +{!> ../docs_src/dependencies/urls_factory_import.py !} +``` + +Now, this is a beauty is it not? This way, the codebase is cleaner and without all of those imported +objects from the top. + +!!! Tip + Both cases work well within Esmerald, this is simply an alternative in case the complexity of + the codebase increases and you would like to tidy it up a bit more. + In conclusion, if your views/routes expect dependencies, you can define them in the upper level as described and Esmerald will make sure that they will be automatically injected. diff --git a/docs_src/dependencies/urls_factory_import.py b/docs_src/dependencies/urls_factory_import.py new file mode 100644 index 00000000..fb17fce7 --- /dev/null +++ b/docs_src/dependencies/urls_factory_import.py @@ -0,0 +1,18 @@ +from esmerald import Factory, Include, Inject + +route_patterns = [ + Include( + "/api/v1", + routes=[ + Include("/accounts", namespace="accounts.v1.urls"), + Include("/articles", namespace="articles.v1.urls"), + Include("/posts", namespace="posts.v1.urls"), + ], + interceptors=[LoggingInterceptor], # Custom interceptor + dependencies={ + "user_dao": Inject(Factory("myapp.accounts.daos.UserDAO")), + "article_dao": Inject(Factory("myapp.articles.daos.ArticleDAO")), + "post_dao": Inject(Factory("myapp.posts.daos.PostDAO")), + }, + ) +] diff --git a/mkdocs.yml b/mkdocs.yml index 6e4b8f9a..09859fd9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -83,9 +83,9 @@ nav: - Interceptors: "interceptors.md" - Permissions: "permissions.md" - Middleware: "middleware/middleware.md" + - Dependencies: "dependencies.md" - Exceptions: "exceptions.md" - Exception Handlers: "exception-handlers.md" - - Dependencies: "dependencies.md" - Pluggables: "pluggables.md" - Datastructures: "datastructures.md" - Password Hashers: "password-hashers.md"