Skip to content

Commit

Permalink
Add a new class DictProvider to handle a dictionary of values. (#35)
Browse files Browse the repository at this point in the history
Add a new class DictProvider to handle a dictionary of values
  • Loading branch information
Denis-Frunza authored Jun 15, 2024
1 parent fa7044e commit 5152b04
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
51 changes: 51 additions & 0 deletions docs/providers/dict.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

# DictProvider
- It allows you to logically group related dependencies together in a dictionary, making it easier to manage and inject them as a single unit.
- It simplifies the injection process when multiple dependencies need to be passed to a component that expects a dictionary of dependencies.

## Example Usage
### Step 1: Define the Dependencies
```python
@dataclasses.dataclass(kw_only=True, slots=True)
class ModuleA:
dependency: str


@dataclasses.dataclass(kw_only=True, slots=True)
class ModuleB:
dependency: str


@dataclasses.dataclass(kw_only=True, slots=True)
class Dispatcher:
modules: Dict[str, Any]

```
### Step 2: Define Providers
Next, define the providers for these dependencies using `Factory` and `DictProvider`.

```python
class DIContainer(BaseContainer):
module_a_provider = providers.Factory(ModuleA, dependency="some_dependency_a")
module_b_provider = providers.Factory(ModuleB, dependency="some_dependency_b")
modules_provider = providers.DictProvider(module1=module_a_provider, module2=module_b_provider)
dispatcher_provider = providers.Factory(Dispatcher, modules=modules_provider)
```

### Step 3: Resolve the Dispatcher
```
dispatcher = DIContainer.dispatcher_provider.sync_resolve()
print(dispatcher.modules["module1"].dependency) # Output: some_dependency_a
print(dispatcher.modules["module2"].dependency) # Output: some_dependency_b
# Asynchronous usage example
import asyncio
async def main():
dispatcher_async = await container.dispatcher_provider.async_resolve()
print(dispatcher_async.modules["module1"].dependency) # Output: real_dependency_a
print(dispatcher_async.modules["module2"].dependency) # Output: real_dependency_b
asyncio.run(main())
```
3 changes: 2 additions & 1 deletion that_depends/providers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from that_depends.providers.base import AbstractProvider, AbstractResource
from that_depends.providers.collections import List
from that_depends.providers.collections import DictProvider, List
from that_depends.providers.context_resources import (
AsyncContextResource,
ContextResource,
Expand All @@ -26,4 +26,5 @@
"Selector",
"Singleton",
"container_context",
"DictProvider",
]
13 changes: 13 additions & 0 deletions that_depends/providers/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,16 @@ def sync_resolve(self) -> list[T]:

async def __call__(self) -> list[T]:
return await self.async_resolve()


class DictProvider(AbstractProvider[dict[str, T]]):
"""Dictionary Provider Class."""

def __init__(self, **providers: AbstractProvider[T]) -> None:
self._providers = providers

async def async_resolve(self) -> dict[str, T]:
return {key: await provider.async_resolve() for key, provider in self._providers.items()}

def sync_resolve(self) -> dict[str, T]:
return {key: provider.sync_resolve() for key, provider in self._providers.items()}

0 comments on commit 5152b04

Please sign in to comment.