-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* inject factories * docs on injecting factories
- Loading branch information
Showing
10 changed files
with
207 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Injecting factories | ||
|
||
When you need to inject the factory itself, but not the result of its call, use: | ||
1. `.provider` attribute for async resolver | ||
2. `.sync_provider` attribute for sync resolver | ||
|
||
Let's first define providers with container: | ||
```python | ||
import dataclasses | ||
import datetime | ||
import typing | ||
|
||
from that_depends import BaseContainer, providers | ||
|
||
|
||
async def create_async_resource() -> typing.AsyncIterator[datetime.datetime]: | ||
yield datetime.datetime.now(tz=datetime.timezone.utc) | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True, slots=True) | ||
class SomeFactory: | ||
start_at: datetime.datetime | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True, slots=True) | ||
class FactoryWithFactories: | ||
sync_factory: typing.Callable[..., SomeFactory] | ||
async_factory: typing.Callable[..., typing.Coroutine[typing.Any, typing.Any, SomeFactory]] | ||
|
||
|
||
class DIContainer(BaseContainer): | ||
async_resource = providers.AsyncResource(create_async_resource) | ||
dependent_factory = providers.Factory(SomeFactory, start_at=async_resource.cast) | ||
factory_with_factories = providers.Factory( | ||
FactoryWithFactories, | ||
sync_factory=dependent_factory.sync_provider, | ||
async_factory=dependent_factory.provider, | ||
) | ||
``` | ||
|
||
Async factory from `.provider` attribute can be used like this: | ||
```python | ||
factory_with_factories = await DIContainer.factory_with_factories() | ||
instance1 = await factory_with_factories.async_factory() | ||
instance2 = await factory_with_factories.async_factory() | ||
assert instance1 is not instance2 | ||
``` | ||
|
||
Sync factory from `.sync_provider` attribute can be used like this: | ||
```python | ||
await DIContainer.init_async_resources() | ||
factory_with_factories = await DIContainer.factory_with_factories() | ||
instance1 = factory_with_factories.sync_factory() | ||
instance2 = factory_with_factories.sync_factory() | ||
assert instance1 is not instance2 | ||
``` |
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import dataclasses | ||
import typing | ||
|
||
import pytest | ||
|
||
from tests import container | ||
from that_depends import BaseContainer, providers | ||
|
||
|
||
@dataclasses.dataclass(kw_only=True, slots=True) | ||
class InjectedFactories: | ||
sync_factory: typing.Callable[..., container.DependentFactory] | ||
async_factory: typing.Callable[..., typing.Coroutine[typing.Any, typing.Any, container.DependentFactory]] | ||
|
||
|
||
class DIContainer(BaseContainer): | ||
sync_resource = providers.Resource(container.create_sync_resource) | ||
async_resource = providers.AsyncResource(container.create_async_resource) | ||
|
||
simple_factory = providers.Factory(container.SimpleFactory, dep1="text", dep2=123) | ||
dependent_factory = providers.Factory( | ||
container.DependentFactory, | ||
simple_factory=simple_factory.cast, | ||
sync_resource=sync_resource.cast, | ||
async_resource=async_resource.cast, | ||
) | ||
injected_factories = providers.Factory( | ||
InjectedFactories, | ||
sync_factory=dependent_factory.sync_provider, | ||
async_factory=dependent_factory.provider, | ||
) | ||
|
||
|
||
async def test_async_provider() -> None: | ||
injected_factories = await DIContainer.injected_factories() | ||
instance1 = await injected_factories.async_factory() | ||
instance2 = await injected_factories.async_factory() | ||
|
||
assert isinstance(instance1, container.DependentFactory) | ||
assert isinstance(instance2, container.DependentFactory) | ||
assert instance1 is not instance2 | ||
|
||
await DIContainer.tear_down() | ||
|
||
|
||
async def test_sync_provider() -> None: | ||
injected_factories = await DIContainer.injected_factories() | ||
with pytest.raises(RuntimeError, match="AsyncResource cannot be resolved synchronously"): | ||
injected_factories.sync_factory() | ||
|
||
await DIContainer.init_async_resources() | ||
instance1 = injected_factories.sync_factory() | ||
instance2 = injected_factories.sync_factory() | ||
|
||
assert isinstance(instance1, container.DependentFactory) | ||
assert isinstance(instance2, container.DependentFactory) | ||
assert instance1 is not instance2 | ||
|
||
await DIContainer.tear_down() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters