diff --git a/docs/docs/debugging/scope-tree.md b/docs/docs/debugging/scope-tree.md
new file mode 100644
index 0000000..6af7d14
--- /dev/null
+++ b/docs/docs/debugging/scope-tree.md
@@ -0,0 +1,5 @@
+---
+title: Scope tree
+description: Visualize your module tree
+sidebar_position: 1
+---
diff --git a/docs/docs/debugging/service-dependencies.md b/docs/docs/debugging/service-dependencies.md
new file mode 100644
index 0000000..383a54c
--- /dev/null
+++ b/docs/docs/debugging/service-dependencies.md
@@ -0,0 +1,5 @@
+---
+title: Service dependencies
+description: Understand your dependency graph
+sidebar_position: 2
+---
diff --git a/docs/docs/debugging/service-registry.md b/docs/docs/debugging/service-registry.md
new file mode 100644
index 0000000..65ddae7
--- /dev/null
+++ b/docs/docs/debugging/service-registry.md
@@ -0,0 +1,67 @@
+---
+title: Service registry
+description: Learn how to troubleshoot service registry
+sidebar_position: 3
+---
+
+# Service registry
+
+## Service name
+
+Each service is identified in the DI container by a slug.
+
+When using implicit naming, the `do` framework infers the service name from the type, by using the [go-type-to-string](https://github.com/samber/go-type-to-string) library.
+
+For debugging purposes, you might want to print the service name.
+
+```go
+i := do.New()
+
+do.Provide(i, func(i do.Injector) (*MyService, error) {
+ return &MyService{}, nil
+})
+
+println(do.Name[*MyService](i))
+// *github.com/samber/example.MyService
+```
+
+## Provided services
+
+For debugging purposes, the list of services provided to the container can be printed:
+
+```go
+i := do.New()
+
+do.Provide(i, func(i do.Injector) (*MyService, error) {
+ return &MyService{}, nil
+})
+do.ProvideNamed(i, "a-number", 42)
+
+services := i.ListProvidedServices()
+println(services)
+// []{
+// {ScopeID: "xxxxx", ScopeName: "[root]", Service: "*github.com/samber/example.MyService"},
+// {ScopeID: "xxxxx", ScopeName: "[root]", Service: "a-number"},
+// }
+```
+
+## Invoked services
+
+For debugging purposes, the list of invoked services can be printed:
+
+```go
+i := do.New()
+
+do.Provide(i, func(i do.Injector) (*MyService, error) {
+ return &MyService{}, nil
+})
+do.ProvideNamed(i, "a-number", 42)
+
+services := i.ListInvokedServices()
+println(services)
+// []{
+// {ScopeID: "xxxxx", ScopeName: "[root]", Service: "a-number"},
+// }
+```
+
+In the example above, the lazy-loaded service `*MyService` has not been invoked.
diff --git a/docs/docs/debugging/to-do-v2.md b/docs/docs/debugging/to-do-v2.md
deleted file mode 100644
index ee3a759..0000000
--- a/docs/docs/debugging/to-do-v2.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 1
----
-
-# To samber/do v2
-
-This documentation will help you upgrade your site from `samber/do` v1 to `samber/do` v2.
-
-`samber/do` v2 is a new major version, including breaking changes requiring you to adjust your applications accordingly. We will guide to during this process, and also mention a few optional recommendations.
-
-This release is large rewrite, but the breaking changes are relatively easy to handle. Some updates can be done with a simple `sed` command.
-
-Check the release notes [here](https://github.com/samber/do/releases).
-
-No breaking change will be done until v3.
-
-## 1- Upgrading package
-
-Update go.mod:
-
-```sh
-go get -u github.com/samber/do/v2
-```
-
-Replace package import:
-
-```sh
-find . -type f -exec sed -i 's#samber/do"#samber/do/v2"#g' {} \;
-```
-
-Cleanup previous dependencies:
-
-```sh
-go mod tidy
-```
-
-## 2- `do.Injector` interface
-
-`do.Injector` has been transformed into an interface. Replace `*do.Injector` by `do.Injector`.
-
-```sh
-find . -type f -exec sed -i "s/*do.Injector/do.Injector/g" {} \;
-```
-
-## 3- `do.Shutdown****` output
-
-Shutdown functions used to return only 1 argument.
-
-```go
-# from
-err := injector.Shutdown()
-
-# to
-signal, err := injector.Shutdown()
-```
diff --git a/docs/docs/glossary.md b/docs/docs/glossary.md
new file mode 100644
index 0000000..8beeb59
--- /dev/null
+++ b/docs/docs/glossary.md
@@ -0,0 +1,68 @@
+---
+id: glossary
+title: Glossary
+description: Dependency injection glossary
+sidebar_position: 6
+---
+
+# Glossary
+
+## Dependency Injection (DI)
+
+A design pattern used in software development to achieve Inversion of Control (IoC) between classes and their dependencies. It's a technique for achieving loose coupling between objects and their collaborators, or dependencies.
+
+## Inversion of Control (IoC)
+
+A design principle where the flow of control is inverted compared to traditional procedural programming. Instead of the application-specific code controlling the execution of reusable code, the reusable code controls the execution. This principle is often implemented using techniques such as Dependency Injection, leading to more modular and easily maintainable code.
+
+## Injector
+
+In Dependency Injection (DI), an injector is a component that creates instances of classes and manages their dependencies. It's also known as the DI container or IoC (Inversion of Control) container.
+
+## DI Container
+
+A DI Container is another term for the Injector in Dependency Injection. It's responsible for providing instances of classes and their dependencies.
+
+## Scope
+
+Kind of module. It contains many declaration singleton and service providers. It has access to the services from ancestors' scopes.
+
+## Root scope
+
+Top-level scope.
+
+## Child scope
+
+A scope that is nested within another scope. Variables defined in a child scope are only accessible within that scope and any nested scopes.
+
+## DAG
+
+Stands for Directed Acyclic Graph. It's a concept in mathematics and computer science. In the context of DI, it often refers to the graph of dependencies between different components or services.
+
+## Provider
+
+In DI, a provider is a component or a factory that creates instances of a service or a class.
+
+## Injection
+
+The process of providing a service to a scope. The injection can be done in different ways like provider injection or setter injection.
+
+## Invocation
+
+The process of executing a procedure or function through a call.
+
+## Lazy Service
+
+A service in DI that is not created until it is first requested.
+
+## Eager Service
+
+A service in DI that is created as soon as the application starts, not when it's first requested.
+
+## Transient Service
+
+A service in DI that is created anew each time it is requested.
+
+## Service Alias
+
+An alternative name given to a service in DI. It allows a service to be accessed using a different identifier.
\ No newline at end of file
diff --git a/docs/docs/scopes/congratulations.md b/docs/docs/scopes/congratulations.md
deleted file mode 100644
index 69ca4cc..0000000
--- a/docs/docs/scopes/congratulations.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 6
----
-
-# Congratulations!
-
-You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
-
-Docusaurus has **much more to offer**!
-
-Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
-
-Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
-
-## What's next?
-
-- Read the [official documentation](https://docusaurus.io/)
-- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config)
-- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration)
-- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
-- Add a [search bar](https://docusaurus.io/docs/search)
-- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
-- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)
diff --git a/docs/docs/scopes/create-a-blog-post.md b/docs/docs/scopes/create-a-blog-post.md
deleted file mode 100644
index 18bca9a..0000000
--- a/docs/docs/scopes/create-a-blog-post.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 3
----
-
-# Create a Blog Post
-
-Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
-
-## Create your first Post
-
-Create a file at `blog/2021-02-28-greetings.md`:
-
-```md title="blog/2021-02-28-greetings.md"
----
-slug: greetings
-title: Greetings!
-authors:
- - name: Joel Marcey
- title: Co-creator of Docusaurus 1
- url: https://github.com/JoelMarcey
- image_url: https://github.com/JoelMarcey.png
- - name: Sébastien Lorber
- title: Docusaurus maintainer
- url: https://sebastienlorber.com
- image_url: https://github.com/slorber.png
-tags: [greetings]
----
-
-Congratulations, you have made your first post!
-
-Feel free to play around and edit this post as much you like.
-```
-
-A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
diff --git a/docs/docs/scopes/create-a-document.md b/docs/docs/scopes/create-a-document.md
deleted file mode 100644
index 7610cb1..0000000
--- a/docs/docs/scopes/create-a-document.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 2
----
-
-# Create a Document
-
-Documents are **groups of pages** connected through:
-
-- a **sidebar**
-- **previous/next navigation**
-- **versioning**
-
-## Create your first Doc
-
-Create a Markdown file at `docs/hello.md`:
-
-```md title="docs/hello.md"
-# Hello
-
-This is my **first Docusaurus document**!
-```
-
-A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello).
-
-## Configure the Sidebar
-
-Docusaurus automatically **creates a sidebar** from the `docs` folder.
-
-Add metadata to customize the sidebar label and position:
-
-```md title="docs/hello.md" {1-4}
----
-sidebar_label: 'Hi!'
-sidebar_position: 3
----
-
-# Hello
-
-This is my **first Docusaurus document**!
-```
-
-It is also possible to create your sidebar explicitly in `sidebars.js`:
-
-```js title="sidebars.js"
-export default {
- docSidebar: [
- 'intro',
- // highlight-next-line
- 'hello',
- {
- type: 'category',
- label: 'Tutorial',
- items: ['tutorial-basics/create-a-document'],
- },
- ],
-};
-```
diff --git a/docs/docs/scopes/deploy-your-site.md b/docs/docs/scopes/deploy-your-site.md
deleted file mode 100644
index 268f9f1..0000000
--- a/docs/docs/scopes/deploy-your-site.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 5
----
-
-# Deploy your site
-
-Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
-
-It builds your site as simple **static HTML, JavaScript and CSS files**.
-
-## Build your site
-
-Build your site **for production**:
-
-```bash
-npm run build
-```
-
-The static files are generated in the `build` folder.
-
-## Deploy your site
-
-Test your production build locally:
-
-```bash
-npm run serve
-```
-
-The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/).
-
-You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).
diff --git a/docs/docs/scopes/fork.md b/docs/docs/scopes/fork.md
new file mode 100644
index 0000000..4b4540f
--- /dev/null
+++ b/docs/docs/scopes/fork.md
@@ -0,0 +1,5 @@
+---
+title: Fork
+description: Clone your global DI container
+sidebar_position: 2
+---
diff --git a/docs/docs/scopes/markdown-features.mdx b/docs/docs/scopes/markdown-features.mdx
deleted file mode 100644
index 2624e92..0000000
--- a/docs/docs/scopes/markdown-features.mdx
+++ /dev/null
@@ -1,152 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 4
----
-
-# Markdown Features
-
-Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
-
-## Front Matter
-
-Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
-
-```text title="my-doc.md"
-// highlight-start
----
-id: my-doc-id
-title: My document title
-description: My document description
-slug: /my-custom-url
----
-// highlight-end
-
-## Markdown heading
-
-Markdown text with [links](./hello.md)
-```
-
-## Links
-
-Regular Markdown links are supported, using url paths or relative file paths.
-
-```md
-Let's see how to [Create a page](/create-a-page).
-```
-
-```md
-Let's see how to [Create a page](./create-a-page.md).
-```
-
-**Result:** Let's see how to [Create a page](./create-a-page.md).
-
-## Images
-
-Regular Markdown images are supported.
-
-You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`):
-
-```md
-![Docusaurus logo](/img/docusaurus.png)
-```
-
-![Docusaurus logo](/img/docusaurus.png)
-
-You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them:
-
-```md
-![Docusaurus logo](./img/docusaurus.png)
-```
-
-## Code Blocks
-
-Markdown code blocks are supported with Syntax highlighting.
-
- ```jsx title="src/components/HelloDocusaurus.js"
- function HelloDocusaurus() {
- return (
-
Hello, Docusaurus!
- )
- }
- ```
-
-```jsx title="src/components/HelloDocusaurus.js"
-function HelloDocusaurus() {
- return Hello, Docusaurus!
;
-}
-```
-
-## Admonitions
-
-Docusaurus has a special syntax to create admonitions and callouts:
-
- :::tip My tip
-
- Use this awesome feature option
-
- :::
-
- :::danger Take care
-
- This action is dangerous
-
- :::
-
-:::tip My tip
-
-Use this awesome feature option
-
-:::
-
-:::danger Take care
-
-This action is dangerous
-
-:::
-
-## MDX and React Components
-
-[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
-
-```jsx
-export const Highlight = ({children, color}) => (
- {
- alert(`You clicked the color ${color} with label ${children}`)
- }}>
- {children}
-
-);
-
-This is Docusaurus green !
-
-This is Facebook blue !
-```
-
-export const Highlight = ({children, color}) => (
- {
- alert(`You clicked the color ${color} with label ${children}`);
- }}>
- {children}
-
-);
-
-This is Docusaurus green !
-
-This is Facebook blue !
diff --git a/docs/docs/scopes/scope.md b/docs/docs/scopes/scope.md
new file mode 100644
index 0000000..7657a8a
--- /dev/null
+++ b/docs/docs/scopes/scope.md
@@ -0,0 +1,5 @@
+---
+title: "Scopes (a.k.a modules)"
+description: Group services into independent modules
+sidebar_position: 1
+---
diff --git a/docs/docs/service-invocation/accept-interfaces-return-structs.md b/docs/docs/service-invocation/accept-interfaces-return-structs.md
new file mode 100644
index 0000000..c347477
--- /dev/null
+++ b/docs/docs/service-invocation/accept-interfaces-return-structs.md
@@ -0,0 +1,103 @@
+---
+title: Accept interfaces, return structs
+description: Accept interfaces, return structs
+sidebar_position: 2
+---
+
+# What the hell?
+
+You have probably already heard the Go proverb "Accept interfaces, return structs". The basic idea is to let the consumer define the interfaces it uses while the producer returns concrete types.
+
+This library offers a great API for assembling a large number of modules with loose coupling and a nice separation of concern.
+
+Aliases must be interface and can be declared explicitly on injection using `do.As()`, or can be invoked implicitly using `do.InvokeAs()`.
+
+## Implicit invocation (prefered)
+
+2 methods are available for implicit invocation:
+- `do.InvokeAs`
+- `do.MustInvokeAs`
+
+Named invocation is not available for now. Please open an issue to discuss about your needs.
+
+Implicit alias is the way to go for production.
+
+```go
+type Metric interface {
+ Inc()
+}
+
+type ReqPerSecond struct {
+ counter int
+}
+
+func (r *ReqPerSecond) Inc() {
+ m.counter++
+}
+
+i := do.New()
+
+// inject the struct
+Provide(i, func(i do.Injector) (*ReqPerSecond, error) {
+ return &ReqPerSecond{}, nil
+})
+
+// invoke using the Metric interface
+metric := do.MustInvokeAs[Metric](injector)
+metric.Inc() // <- r.counter will be incremented
+```
+
+:::info
+
+The first matching service in the scope tree is returned.
+
+:::
+
+## Explicit injection
+
+Explicit injection will be used in rare cases when you need to adapt to legacy code or change the catalog of services at runtime.
+
+If you rely a lot on `do.Scope`, explicit injection might be used to define custom aliases in the scope tree branchs.
+
+4 methods are available for explicit aliasing:
+- `do.As`
+- `do.MustAs`
+- `do.NamedAs`
+- `do.MustNamedAs`
+
+```go
+type Metric interface {
+ Inc()
+}
+
+type ReqPerSecond struct {
+ counter int
+}
+
+func (r *ReqPerSecond) Inc() {
+ m.counter++
+}
+
+i := do.New()
+
+// inject the struct
+Provide(i, func(i do.Injector) (*ReqPerSecond, error) {
+ return &ReqPerSecond{}, nil
+})
+
+// explicit aliasing
+err := do.As[*ReqPerSecond, Metric](injector)
+if err != nil {
+ // ...
+}
+
+// invoke using the explicit alias
+metric := do.MustInvoke[Metric](injector)
+metric.Inc() // <- r.counter will be incremented
+```
+
+:::danger
+
+Explicit aliasing is pure shit and should be used very carefully. You've been warned. 😁
+
+:::
diff --git a/docs/docs/service-invocation/manage-docs-versions.md b/docs/docs/service-invocation/manage-docs-versions.md
deleted file mode 100644
index 2323ab9..0000000
--- a/docs/docs/service-invocation/manage-docs-versions.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 1
----
-
-# Manage Docs Versions
-
-Docusaurus can manage multiple versions of your docs.
-
-## Create a docs version
-
-Release a version 1.0 of your project:
-
-```bash
-npm run docusaurus docs:version 1.0
-```
-
-The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
-
-Your docs now have 2 versions:
-
-- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
-- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
-
-## Add a Version Dropdown
-
-To navigate seamlessly across versions, add a version dropdown.
-
-Modify the `docusaurus.config.js` file:
-
-```js title="docusaurus.config.js"
-export default {
- themeConfig: {
- navbar: {
- items: [
- // highlight-start
- {
- type: 'docsVersionDropdown',
- },
- // highlight-end
- ],
- },
- },
-};
-```
-
-The docs version dropdown appears in your navbar:
-
-## Update an existing version
-
-It is possible to edit versioned docs in their respective folder:
-
-- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
-- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`
diff --git a/docs/docs/service-invocation/service-invocation.md b/docs/docs/service-invocation/service-invocation.md
new file mode 100644
index 0000000..b17dd07
--- /dev/null
+++ b/docs/docs/service-invocation/service-invocation.md
@@ -0,0 +1,6 @@
+---
+title: Service invocation
+description: Invoke eager or lazy services from the DI container
+sidebar_position: 1
+---
+
diff --git a/docs/docs/service-invocation/translate-your-site.md b/docs/docs/service-invocation/translate-your-site.md
deleted file mode 100644
index f687193..0000000
--- a/docs/docs/service-invocation/translate-your-site.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 2
----
-
-# Translate your site
-
-Let's translate `docs/intro.md` to French.
-
-## Configure i18n
-
-Modify `docusaurus.config.js` to add support for the `fr` locale:
-
-```js title="docusaurus.config.js"
-export default {
- i18n: {
- defaultLocale: 'en',
- locales: ['en', 'fr'],
- },
-};
-```
-
-## Translate a doc
-
-Copy the `docs/intro.md` file to the `i18n/fr` folder:
-
-```bash
-mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
-
-cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md
-```
-
-Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French.
-
-## Start your localized site
-
-Start your site on the French locale:
-
-```bash
-npm run start -- --locale fr
-```
-
-Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated.
-
-:::caution
-
-In development, you can only use one locale at a time.
-
-:::
-
-## Add a Locale Dropdown
-
-To navigate seamlessly across languages, add a locale dropdown.
-
-Modify the `docusaurus.config.js` file:
-
-```js title="docusaurus.config.js"
-export default {
- themeConfig: {
- navbar: {
- items: [
- // highlight-start
- {
- type: 'localeDropdown',
- },
- // highlight-end
- ],
- },
- },
-};
-```
-
-The locale dropdown now appears in your navbar:
-
-## Build your localized site
-
-Build your site for a specific locale:
-
-```bash
-npm run build -- --locale fr
-```
-
-Or build your site to include all the locales at once:
-
-```bash
-npm run build
-```
diff --git a/docs/docs/service-lifecycle/congratulations.md b/docs/docs/service-lifecycle/congratulations.md
deleted file mode 100644
index 69ca4cc..0000000
--- a/docs/docs/service-lifecycle/congratulations.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 6
----
-
-# Congratulations!
-
-You have just learned the **basics of Docusaurus** and made some changes to the **initial template**.
-
-Docusaurus has **much more to offer**!
-
-Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**.
-
-Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610)
-
-## What's next?
-
-- Read the [official documentation](https://docusaurus.io/)
-- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config)
-- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration)
-- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout)
-- Add a [search bar](https://docusaurus.io/docs/search)
-- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase)
-- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support)
diff --git a/docs/docs/service-lifecycle/create-a-blog-post.md b/docs/docs/service-lifecycle/create-a-blog-post.md
deleted file mode 100644
index 18bca9a..0000000
--- a/docs/docs/service-lifecycle/create-a-blog-post.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 3
----
-
-# Create a Blog Post
-
-Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed...
-
-## Create your first Post
-
-Create a file at `blog/2021-02-28-greetings.md`:
-
-```md title="blog/2021-02-28-greetings.md"
----
-slug: greetings
-title: Greetings!
-authors:
- - name: Joel Marcey
- title: Co-creator of Docusaurus 1
- url: https://github.com/JoelMarcey
- image_url: https://github.com/JoelMarcey.png
- - name: Sébastien Lorber
- title: Docusaurus maintainer
- url: https://sebastienlorber.com
- image_url: https://github.com/slorber.png
-tags: [greetings]
----
-
-Congratulations, you have made your first post!
-
-Feel free to play around and edit this post as much you like.
-```
-
-A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
diff --git a/docs/docs/service-lifecycle/create-a-document.md b/docs/docs/service-lifecycle/create-a-document.md
deleted file mode 100644
index 7610cb1..0000000
--- a/docs/docs/service-lifecycle/create-a-document.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 2
----
-
-# Create a Document
-
-Documents are **groups of pages** connected through:
-
-- a **sidebar**
-- **previous/next navigation**
-- **versioning**
-
-## Create your first Doc
-
-Create a Markdown file at `docs/hello.md`:
-
-```md title="docs/hello.md"
-# Hello
-
-This is my **first Docusaurus document**!
-```
-
-A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello).
-
-## Configure the Sidebar
-
-Docusaurus automatically **creates a sidebar** from the `docs` folder.
-
-Add metadata to customize the sidebar label and position:
-
-```md title="docs/hello.md" {1-4}
----
-sidebar_label: 'Hi!'
-sidebar_position: 3
----
-
-# Hello
-
-This is my **first Docusaurus document**!
-```
-
-It is also possible to create your sidebar explicitly in `sidebars.js`:
-
-```js title="sidebars.js"
-export default {
- docSidebar: [
- 'intro',
- // highlight-next-line
- 'hello',
- {
- type: 'category',
- label: 'Tutorial',
- items: ['tutorial-basics/create-a-document'],
- },
- ],
-};
-```
diff --git a/docs/docs/service-lifecycle/deploy-your-site.md b/docs/docs/service-lifecycle/deploy-your-site.md
deleted file mode 100644
index 268f9f1..0000000
--- a/docs/docs/service-lifecycle/deploy-your-site.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 5
----
-
-# Deploy your site
-
-Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**).
-
-It builds your site as simple **static HTML, JavaScript and CSS files**.
-
-## Build your site
-
-Build your site **for production**:
-
-```bash
-npm run build
-```
-
-The static files are generated in the `build` folder.
-
-## Deploy your site
-
-Test your production build locally:
-
-```bash
-npm run serve
-```
-
-The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/).
-
-You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**).
diff --git a/docs/docs/service-lifecycle/healthchecker.md b/docs/docs/service-lifecycle/healthchecker.md
new file mode 100644
index 0000000..6f1471c
--- /dev/null
+++ b/docs/docs/service-lifecycle/healthchecker.md
@@ -0,0 +1,5 @@
+---
+title: Healthcheckable services
+description: Track the service status
+sidebar_position: 1
+---
diff --git a/docs/docs/service-lifecycle/markdown-features.mdx b/docs/docs/service-lifecycle/markdown-features.mdx
deleted file mode 100644
index 2624e92..0000000
--- a/docs/docs/service-lifecycle/markdown-features.mdx
+++ /dev/null
@@ -1,152 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 4
----
-
-# Markdown Features
-
-Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**.
-
-## Front Matter
-
-Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/):
-
-```text title="my-doc.md"
-// highlight-start
----
-id: my-doc-id
-title: My document title
-description: My document description
-slug: /my-custom-url
----
-// highlight-end
-
-## Markdown heading
-
-Markdown text with [links](./hello.md)
-```
-
-## Links
-
-Regular Markdown links are supported, using url paths or relative file paths.
-
-```md
-Let's see how to [Create a page](/create-a-page).
-```
-
-```md
-Let's see how to [Create a page](./create-a-page.md).
-```
-
-**Result:** Let's see how to [Create a page](./create-a-page.md).
-
-## Images
-
-Regular Markdown images are supported.
-
-You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`):
-
-```md
-![Docusaurus logo](/img/docusaurus.png)
-```
-
-![Docusaurus logo](/img/docusaurus.png)
-
-You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them:
-
-```md
-![Docusaurus logo](./img/docusaurus.png)
-```
-
-## Code Blocks
-
-Markdown code blocks are supported with Syntax highlighting.
-
- ```jsx title="src/components/HelloDocusaurus.js"
- function HelloDocusaurus() {
- return (
- Hello, Docusaurus!
- )
- }
- ```
-
-```jsx title="src/components/HelloDocusaurus.js"
-function HelloDocusaurus() {
- return Hello, Docusaurus!
;
-}
-```
-
-## Admonitions
-
-Docusaurus has a special syntax to create admonitions and callouts:
-
- :::tip My tip
-
- Use this awesome feature option
-
- :::
-
- :::danger Take care
-
- This action is dangerous
-
- :::
-
-:::tip My tip
-
-Use this awesome feature option
-
-:::
-
-:::danger Take care
-
-This action is dangerous
-
-:::
-
-## MDX and React Components
-
-[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**:
-
-```jsx
-export const Highlight = ({children, color}) => (
- {
- alert(`You clicked the color ${color} with label ${children}`)
- }}>
- {children}
-
-);
-
-This is Docusaurus green !
-
-This is Facebook blue !
-```
-
-export const Highlight = ({children, color}) => (
- {
- alert(`You clicked the color ${color} with label ${children}`);
- }}>
- {children}
-
-);
-
-This is Docusaurus green !
-
-This is Facebook blue !
diff --git a/docs/docs/service-lifecycle/shutdowner.md b/docs/docs/service-lifecycle/shutdowner.md
new file mode 100644
index 0000000..abae20b
--- /dev/null
+++ b/docs/docs/service-lifecycle/shutdowner.md
@@ -0,0 +1,83 @@
+---
+title: Shutdownable services
+description: Graceful service shutdown
+sidebar_position: 2
+---
+
+# Graceful service shutdown
+
+If your service brings a state such as a connection pool, a buffer, etc... you might want to close or flush it gracefully on the application exit.
+
+When the `injector.Shutdown()` function is called, the framework triggers `Shutdown` method of each service implementing a `Shutdowner` interface, in reverse invocation order.
+
+## Trigger shutdown
+
+A shutdown can be triggered for a root injector:
+
+```go
+// proactive
+injector.Shutdown() error
+injector.ShutdownWithContext(context.Context) error
+
+// on signal
+injector.ShutdownOnSignals(...os.Signal) (os.Signal, error)
+injector.ShutdownOnSignalsWithContext(context.Context, ...os.Signal) (os.Signal, error)
+```
+
+...or a single service:
+
+```go
+// returns error on failure
+do.Shutdown[T any](do.Injector) error
+do.ShutdownNamed[T any](do.Injector, string) error
+do.ShutdownWithContext[T any](context.Context, do.Injector) error
+do.ShutdownNamedWithContext[T any](context.Context, do.Injector, string) error
+
+// panics on failure
+do.MustShutdown[T any](do.Injector)
+do.MustShutdownNamed[T any](do.Injector, string)
+do.MustShutdownWithContext[T any](context.Context, do.Injector)
+do.MustShutdownNamedWithContext[T any](context.Context, do.Injector, string)
+```
+
+## Shutdowner interfaces
+
+Your service can implement one of the following signatures:
+
+```go
+type Shutdowner interface {
+ Shutdown()
+}
+
+type ShutdownerWithError interface {
+ Shutdown() error
+}
+
+type ShutdownerWithContext interface {
+ Shutdown(context.Context)
+}
+
+type ShutdownerWithContextAndError interface {
+ Shutdown(context.Context) error
+}
+```
+
+Example:
+
+```go
+type MyService struct {}
+
+func (*MyService) Shutdown(context.Context) error {
+ // ...
+ return nil
+}
+
+i := do.New()
+
+Provide(i, ...)
+Invoke(i, ...)
+
+ctx := context.WithTimeout(1 * time.Second)
+i.ShutdownWithContext(ctx)
+```
+
diff --git a/docs/docs/service-registration/eager-loading.md b/docs/docs/service-registration/eager-loading.md
new file mode 100644
index 0000000..3489692
--- /dev/null
+++ b/docs/docs/service-registration/eager-loading.md
@@ -0,0 +1,83 @@
+---
+title: Eager loading
+description: Eager loading initializes a resource as soon as the code is executed.
+sidebar_position: 2
+---
+
+# Eager loading
+
+Eager loading initializes a resource as soon as the code is executed.
+
+## Inject service into DI container
+
+An eager service is simply initialized by you and then injected into the DI container.
+
+A service can be injected in many ways. Here is the full list of lazy loading service injections.
+
+```go
+func ProvideValue[T any](i do.Injector, value T)
+func ProvideNamedValue[T any](i do.Injector, name string, value T)
+func OverrideValue[T any](i do.Injector, value T)
+func OverrideNamedValue[T any](i do.Injector, name string, value T)
+```
+
+:::info
+
+This is highly recommended to use the anonymous service invocation to let the framework handle naming.
+
+:::
+
+```go
+type Config struct {
+ Port int
+}
+config := &Config{
+ Port: os.Getenv("PORT"),
+}
+
+i := do.New()
+
+do.ProvideValue(i, config)
+// or
+do.ProvideNamedValue(i, "my.really.cool.config", config)
+```
+
+## Hot service replacement
+
+By default, providing a service twice will panic. Service can be replaced at runtime using `do.Override` helper.
+
+For test purposes, it can be very useful to override a service given to the DI container.
+
+:::warning
+
+We highly discourage using this helper in production. Please use service aliasing instead.
+
+:::
+
+```go
+type CalculatorTestSuite struct {
+ suite.Suite
+ i do.Injector
+}
+
+func (suite *CalculatorTestSuite) SetupSuite() {
+ suite.i = do.New()
+ do.ProvideNamedValue(suite.i, "a-number", 42)
+}
+
+func (suite *CalculatorTestSuite) TearDownSuite() {
+ suite.i.Shutdown()
+}
+
+func (suite *CalculatorTestSuite) SetupTest() {
+ do.OverrideNamedValue(suite.i, "a-number", 1337) // <- replace service by mock
+}
+
+func (suite *CalculatorTestSuite) Test1() {
+ // ...
+}
+
+func (suite *CalculatorTestSuite) Test2() {
+ // ...
+}
+```
diff --git a/docs/docs/service-registration/lazy-loading.md b/docs/docs/service-registration/lazy-loading.md
new file mode 100644
index 0000000..4a62218
--- /dev/null
+++ b/docs/docs/service-registration/lazy-loading.md
@@ -0,0 +1,98 @@
+---
+title: Lazy loading
+description: Lazy loading limits the number of components that load in an app.
+sidebar_position: 1
+---
+
+# Lazy loading
+
+Lazy loading limits the number of components that load in an app.
+
+## Provider
+
+A lazy service must be defined with a `provider` (kind of constructor). This provider will be called once and must return the singleton or an error.
+
+```go
+type Provider[T any] func(do.Injector) (T, error)
+```
+
+Example:
+
+```go
+type MyService struct {
+ Hello string
+}
+
+func NewMyService(i do.Injector) (*MyService, error) {
+ return &MyService{Hello: "world"}, nil
+}
+```
+
+## Inject service into DI container
+
+A service can be injected in many ways. Here is the full list of lazy loading service injections.
+
+```go
+func Provide[T any](i do.Injector, provider do.Provider[T])
+func ProvideNamed[T any](i do.Injector, name string, provider do.Provider[T])
+func Override[T any](i do.Injector, provider Provider[T])
+func OverrideNamed[T any](i do.Injector, name string, provider do.Provider[T])
+```
+
+:::info
+
+This is highly recommended to use the anonymous service invocation to let the framework handle naming.
+
+:::
+
+```go
+i := do.New()
+
+do.Provide(i, NewMyService)
+// or
+do.ProvideNamed(i, "my.really.cool.service", NewMyService)
+```
+
+## Error handling
+
+On invocation, panics are cought by the framework and returned as an error.
+
+## Hot service replacement
+
+By default, providing a service twice will panic. Service can be replaced at runtime using `do.Override` helper.
+
+For test purposes, it can be very useful to override a service given to the DI container.
+
+:::warning
+
+We highly discourage using this helper in production. Please use service aliasing instead.
+
+:::
+
+```go
+type CalculatorTestSuite struct {
+ suite.Suite
+ i do.Injector
+}
+
+func (suite *CalculatorTestSuite) SetupSuite() {
+ suite.i = do.New()
+ do.Provide(suite.i, NewMyService)
+}
+
+func (suite *CalculatorTestSuite) TearDownSuite() {
+ suite.i.Shutdown()
+}
+
+func (suite *CalculatorTestSuite) SetupTest() {
+ do.Override(suite.i, NewMyServiceMock) // <- replace service by mock
+}
+
+func (suite *CalculatorTestSuite) Test1() {
+ // ...
+}
+
+func (suite *CalculatorTestSuite) Test2() {
+ // ...
+}
+```
diff --git a/docs/docs/service-registration/manage-docs-versions.md b/docs/docs/service-registration/manage-docs-versions.md
deleted file mode 100644
index 2323ab9..0000000
--- a/docs/docs/service-registration/manage-docs-versions.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 1
----
-
-# Manage Docs Versions
-
-Docusaurus can manage multiple versions of your docs.
-
-## Create a docs version
-
-Release a version 1.0 of your project:
-
-```bash
-npm run docusaurus docs:version 1.0
-```
-
-The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created.
-
-Your docs now have 2 versions:
-
-- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs
-- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs**
-
-## Add a Version Dropdown
-
-To navigate seamlessly across versions, add a version dropdown.
-
-Modify the `docusaurus.config.js` file:
-
-```js title="docusaurus.config.js"
-export default {
- themeConfig: {
- navbar: {
- items: [
- // highlight-start
- {
- type: 'docsVersionDropdown',
- },
- // highlight-end
- ],
- },
- },
-};
-```
-
-The docs version dropdown appears in your navbar:
-
-## Update an existing version
-
-It is possible to edit versioned docs in their respective folder:
-
-- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello`
-- `docs/hello.md` updates `http://localhost:3000/docs/next/hello`
diff --git a/docs/docs/service-registration/transient-loading.md b/docs/docs/service-registration/transient-loading.md
new file mode 100644
index 0000000..3abfd93
--- /dev/null
+++ b/docs/docs/service-registration/transient-loading.md
@@ -0,0 +1,98 @@
+---
+title: Transient loading
+description: Transient loading is a factory catalog
+sidebar_position: 3
+---
+
+# Transient loading - a.k.a Factory
+
+Transient loading is similar to lazy loading, but a new instance is provided at every invocation. It can be considered as a factory registry.
+
+## Provider
+
+A transient service must be defined with a `provider` (kind of constructor). This provider will be called at every invocation.
+
+```go
+type Provider[T any] func(do.Injector) (T, error)
+```
+
+Example:
+
+```go
+type MyService struct {
+ Hello string
+}
+
+func NewMyService(i do.Injector) (*MyService, error) {
+ return &MyService{Hello: "world"}, nil
+}
+```
+
+## Inject service into DI container
+
+A service can be injected in many ways. Here is the full list of transient loading service injections.
+
+```go
+func ProvideTransient[T any](i do.Injector, provider do.Provider[T])
+func ProvideNamedTransient[T any](i do.Injector, name string, provider do.Provider[T])
+func OverrideTransient[T any](i do.Injector, provider Provider[T])
+func OverrideNamedTransient[T any](i do.Injector, name string, provider do.Provider[T])
+```
+
+:::info
+
+This is highly recommended to use the anonymous service invocation to let the framework handle naming.
+
+:::
+
+```go
+i := do.New()
+
+do.ProvideTransient(i, NewMyService)
+// or
+do.ProvideNamedTransient(i, "my.really.cool.service", NewMyService)
+```
+
+## Error handling
+
+On invocation, panics are cought by the framework and returned as an error.
+
+## Hot service replacement
+
+By default, providing a service twice will panic. Service can be replaced at runtime using `do.Override` helper.
+
+For test purposes, it can be very useful to override a service given to the DI container.
+
+:::warning
+
+We highly discourage using this helper in production. Please use service aliasing instead.
+
+:::
+
+```go
+type CalculatorTestSuite struct {
+ suite.Suite
+ i do.Injector
+}
+
+func (suite *CalculatorTestSuite) SetupSuite() {
+ suite.i = do.New()
+ do.ProvideTransient(suite.i, NewMyService)
+}
+
+func (suite *CalculatorTestSuite) TearDownSuite() {
+ suite.i.Shutdown()
+}
+
+func (suite *CalculatorTestSuite) SetupTest() {
+ do.OverrideTransient(suite.i, NewMyServiceMock) // <- replace service by mock
+}
+
+func (suite *CalculatorTestSuite) Test1() {
+ // ...
+}
+
+func (suite *CalculatorTestSuite) Test2() {
+ // ...
+}
+```
diff --git a/docs/docs/service-registration/translate-your-site.md b/docs/docs/service-registration/translate-your-site.md
deleted file mode 100644
index f687193..0000000
--- a/docs/docs/service-registration/translate-your-site.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: my hello page title
-description: my hello page description
-sidebar_position: 2
----
-
-# Translate your site
-
-Let's translate `docs/intro.md` to French.
-
-## Configure i18n
-
-Modify `docusaurus.config.js` to add support for the `fr` locale:
-
-```js title="docusaurus.config.js"
-export default {
- i18n: {
- defaultLocale: 'en',
- locales: ['en', 'fr'],
- },
-};
-```
-
-## Translate a doc
-
-Copy the `docs/intro.md` file to the `i18n/fr` folder:
-
-```bash
-mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/
-
-cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md
-```
-
-Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French.
-
-## Start your localized site
-
-Start your site on the French locale:
-
-```bash
-npm run start -- --locale fr
-```
-
-Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated.
-
-:::caution
-
-In development, you can only use one locale at a time.
-
-:::
-
-## Add a Locale Dropdown
-
-To navigate seamlessly across languages, add a locale dropdown.
-
-Modify the `docusaurus.config.js` file:
-
-```js title="docusaurus.config.js"
-export default {
- themeConfig: {
- navbar: {
- items: [
- // highlight-start
- {
- type: 'localeDropdown',
- },
- // highlight-end
- ],
- },
- },
-};
-```
-
-The locale dropdown now appears in your navbar:
-
-## Build your localized site
-
-Build your site for a specific locale:
-
-```bash
-npm run build -- --locale fr
-```
-
-Or build your site to include all the locales at once:
-
-```bash
-npm run build
-```
diff --git a/docs/docs/upgrading/_category_.json b/docs/docs/upgrading/_category_.json
index 85388a5..cbd54e0 100644
--- a/docs/docs/upgrading/_category_.json
+++ b/docs/docs/upgrading/_category_.json
@@ -1,6 +1,6 @@
{
"label": "Upgrading",
- "position": 6,
+ "position": 7,
"link": {
"type": "generated-index",
"description": "Upgrade to the latest samber/do release"
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index 91276bf..5df5048 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -152,6 +152,9 @@ const config: Config = {
// contextualSearch: false
// },
} satisfies Preset.ThemeConfig,
+
+ plugins: [
+ ],
};
export default config;