Open panicoenlaxbox opened 2 years ago
After writing my issue, I have been thinking about it and with a few changes, I can achieve the same result in a more best way, I think. With this solution, I am using the proposed configuration provider but also, I have an options pattern implementation. The best of both worlds.
containers.py
import json
from typing import Dict, Any
from dacite import from_dict
from dependency_injector import providers
from dependency_injector.containers import DeclarativeContainer, WiringConfiguration
from foo_options import FooOptions
def _from_json() -> Dict[str, Any]:
with open("config.json") as f:
return json.loads(f.read())
def _create_foo_options(config: Dict[str, Any]) -> FooOptions:
return from_dict(FooOptions, config["foo"])
class Container(DeclarativeContainer):
wiring_config = WiringConfiguration(
modules=["__main__"]
)
config = providers.Configuration()
config.from_dict(_from_json())
# This works, but I think it's better to use the dacite library for complex objects
# foo_options = providers.Singleton(FooOptions, bar=config.foo.bar, baz=config.foo.baz)
foo_options = providers.Singleton(_create_foo_options, config)
main.py
from typing import Any, Dict
from dependency_injector.wiring import inject, Provide
from containers import Container
from foo_options import FooOptions
@inject
def main(config: Dict[str, Any] = Provide[Container.config], foo_options: FooOptions = Provide[Container.foo_options]):
print(config) # {'foo': {'bar': 'bar', 'baz': 'baz'}, 'qux': 'qux'}
print(foo_options) # FooOptions(bar='bar', baz='baz')
if __name__ == '__main__':
container = Container()
main()
Hello,
I'm a happy user of your package, it's awesome. I come from the .NET stack and find it very useful in Python.
I don't know if it is available or not in the package, but I miss a couple of things that I used a lot in .NET applications.
The first one is the possibility of loading configuration from a .json file. I know that I can use
.ini
,.yaml
, and other formats, but I think it would be good to support.json
also.The second one, and the most important in my opinion, is don't have something similar to this out-of-the-box https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0
The idea behind this, it's to allow to inject "part" of the configuration like an object. For now, I'm using a workaround that works perfectly.
config.json
foo_options.py
containers.py
main.py
I would like to know your opinion about this. What I want to avoid is having a big object with all my configuration when a class only needs to be aware of a little part. I know that I can inject concrete values of config using Configuration provider or even the whole config like a dict, but I want to use dataclasses with types safety and don't use primitive values.
Congrats for your great job, I couldn't live without this package :)