Package: lidipy
Lidi (LIghtweight Dependency Injector)Lidi is a lightweight dependency injector designed to simplify dependency management in your Python projects.
It provides a simple and intuitive API for binding classes and resolving dependencies.InstallationYou can install Lidi using pip:pipinstalllidipyUsageBasic BindingTo bind a class to an instance or a callable, you can use thebind()method of theLidiinstance:fromlidipyimportLidiclassParent:passclassChild:passlidi=Lidi()# bind instancelidi.bind(Parent,Child())# or bind a callablelidi.bind(Parent,Child)Singleton BindingIf you want to bind a class as a singleton, you can pass thesingletonparameter asTruewhen calling thebind()method:lidi.bind(Parent,Child(),singleton=True)With singleton binding, the same instance of the class will be returned every time it is resolved.Resolving DependenciesTo resolve a class and its dependencies, you can use theresolve()method of the Lidi class:instance=lidi.resolve(Parent)# instance is Child()If the class was bound as a singleton, the same instance will be returned each time it is resolved.Deferred ResolutionLidi also supports deferred resolution using the resolve_defer() method. This method returns a callable that, when invoked, resolves the class:deferred_resolve=lidi.resolve_defer(Parent)instance=deferred_resolve()Deferred resolution can be useful when you want to defer the instantiation of a class until it is actually needed.Handling Missing BindingsIf a binding is missing for a requested type, aBindingMissingexception will be raised.
You can handle this exception and provide appropriate error handling in your application.fromlidipyimportBindingMissingtry:instance=lidi.resolve(Mother)exceptBindingMissingase:print(e)# Outputs: "Binding missing for type: Mother"Usage with DataclassesLidi can be used seamlessly with Python's dataclasses. Here's an example of how to use dataclasses with Lidi:fromdataclassesimportdataclassfromlidipyimportLidilidi=Lidi()@dataclass(frozen=True)classConfig:db_url:str# Bind Configlidi.bind(Config,Config(db_url="example.com:5432"))@dataclassclassDatabase:config:Config=lidi.resolve(Config)defconnect(self):print(f"Connecting to database at{self.config.db_url}")# Bind Databaselidi.bind(Database,Database)# Resolve the dataclass with dependenciesdatabase=lidi.resolve(Database)database.connect()# Output: Connecting to database at example.com:5432Dynamic binds on runtineLidi supports bindings change on runtime, here's an example:fromdataclassesimportdataclass,fieldfromlidipyimportLidilidi=Lidi()@dataclassclassConfig:db_url:str@dataclassclassDatabase:config:Config=field(default_factory=lidi.resolve_defer(Config))defconnect(self):print(f"Connecting to database at{self.config.db_url}")# Bind the initial dependencieslidi.bind(Config,Config(db_url="example.com:5432"))lidi.bind(Database,Database)# Initial resolvedatabase=lidi.resolve(Database)database.connect()# Output: Connecting to database at example.com:5432# Dynamically change bindinglidi.bind(Config,Config(db_url="other-example.com:5432"))# Second resolvedatabase=lidi.resolve(Database)database.connect()# Output: Connecting to database at other-example.com:5432ContributingContributions are welcome! If you find a bug or want to suggest an improvement, please open an issue or submit a pull request on the GitHub repository.LicenseLidi is licensed under the MIT License.
Feel free to use, modify, and distribute this project as per the terms of the license.