Metadata-Version: 2.4
Name: inject-x
Version: 0.0.2
Summary: Natural language request to json converter library
Author-email: Colageo Mirko <mirko.colageo@gmail.com>
License: MIT License
Project-URL: Homepage, https://github.com/bocejo5/injectx
Project-URL: Documentation, https://github.com/bocejo5/injectx
Project-URL: Repository, https://github.com/bocejo5/injectx
Project-URL: Issues, https://github.com/bocejo5/injectx/issues
Keywords: ioc,dependency injection,inversion of control,automatic class loader
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11.5
Description-Content-Type: text/markdown
Requires-Dist: backports.tarfile==1.2.0
Requires-Dist: build==1.2.2.post1
Requires-Dist: bumpver==2024.1130
Requires-Dist: certifi==2025.1.31
Requires-Dist: cffi==1.17.1
Requires-Dist: charset-normalizer==3.4.1
Requires-Dist: click==8.1.8
Requires-Dist: colorama==0.4.6
Requires-Dist: cryptography==43.0.3
Requires-Dist: docutils==0.21.2
Requires-Dist: id==1.5.0
Requires-Dist: idna==3.10
Requires-Dist: importlib_metadata==8.6.1
Requires-Dist: injector==0.22.0
Requires-Dist: jaraco.classes==3.4.0
Requires-Dist: jaraco.context==6.0.1
Requires-Dist: jaraco.functools==4.1.0
Requires-Dist: jeepney==0.9.0
Requires-Dist: keyring==25.6.0
Requires-Dist: lexid==2021.1006
Requires-Dist: markdown-it-py==3.0.0
Requires-Dist: mdurl==0.1.2
Requires-Dist: more-itertools==10.6.0
Requires-Dist: nh3==0.2.21
Requires-Dist: packaging==24.2
Requires-Dist: pycparser==2.22
Requires-Dist: Pygments==2.19.1
Requires-Dist: pyproject_hooks==1.2.0
Requires-Dist: readme_renderer==44.0
Requires-Dist: requests==2.32.3
Requires-Dist: requests-toolbelt==1.0.0
Requires-Dist: rfc3986==2.0.0
Requires-Dist: rich==13.9.4
Requires-Dist: SecretStorage==3.3.3
Requires-Dist: toml==0.10.2
Requires-Dist: tomli==2.2.1
Requires-Dist: twine==6.1.0
Requires-Dist: typing_extensions==4.12.2
Requires-Dist: urllib3==2.3.0
Requires-Dist: zipp==3.21.0

# inject-x

> Dependency injection for Python with automatic class discovery.

Built on top of [injector](https://pypi.org/project/injector/), `inject-x` adds auto-loading from a folder and retrieval of all instances by base type — removing the need to manually register every class.

## Installation

```bash
pip install inject-x
```

**Requirements:** Python >= 3.11.5, `injector >= 0.22.0`

## Quick start

```python
from injectx import Injector, Presentation, Service, Repository, Config

# Load and register all eligible classes from a folder (recursive)
inj = Injector().register_all_from_folder("myapp/")

# Retrieve a specific instance
my_service = inj.get(MyService)

# Retrieve all registered instances of a base type
presentations = inj.get_all_by_type(Presentation)
```

## Base classes

Annotate your classes by inheriting from one of the four base types:

| Class | Intended use |
|-------|-------------|
| `Presentation` | Controllers, API handlers, CLI entry points |
| `Service` | Business logic |
| `Repository` | Data access (DB, external APIs) |
| `Config` | Configuration objects |

Only classes that inherit from one of these will be picked up by `register_all_from_folder`. Classes that don't inherit from any of them (like plain helpers) are ignored.

## API

### `Injector(folder_path_to_register="")`

Creates a new injector. Optionally accepts a folder path to auto-register on construction.

```python
inj = Injector("myapp/")
# equivalent to:
inj = Injector().register_all_from_folder("myapp/")
```

---

### `register_all_from_folder(folder: str) -> Injector`

Recursively walks `folder`, imports every `.py` file (skipping `__init__.py`), and registers all classes that inherit from `Presentation`, `Service`, `Repository`, or `Config` as **singletons**.

- Returns `self` for chaining.
- Modules are loaded with their full dotted name (e.g. `myapp.services.user_service`), consistent with normal Python imports — so `injector.get(MyService)` and `from myapp.services.user_service import MyService` refer to the exact same class object.
- Calling `register_all_from_folder` (or `register`) twice with the same class is a no-op.

```python
inj = (
    Injector()
    .register_all_from_folder("myapp/services/")
    .register_all_from_folder("myapp/repositories/")
)
```

---

### `register(cls) -> None`

Manually registers a single class as a singleton. Useful when auto-discovery is not needed.

```python
inj = Injector()
inj.register(MyService)
```

---

### `get(cls) -> instance`

Returns the singleton instance for the given class.

```python
svc = inj.get(MyService)
```

---

### `get_all_by_type(base_class) -> list`

Returns the singleton instances of all registered classes that are subclasses of `base_class`, traversing the full inheritance hierarchy recursively.

```python
from injectx import Injector, Presentation

class Handler(Presentation): ...
class SpecialHandler(Handler): ...

inj = Injector()
inj.register(Handler)
inj.register(SpecialHandler)

inj.get_all_by_type(Presentation)  # [<Handler>, <SpecialHandler>]
```

## Example project layout

```
myapp/
├── presentation/
│   └── user_controller.py   # class UserController(Presentation): ...
├── services/
│   └── user_service.py      # class UserService(Service): ...
└── repositories/
    └── user_repo.py         # class UserRepo(Repository): ...
```

```python
from injectx import Injector, Service

inj = Injector().register_all_from_folder("myapp/")

# All services, regardless of nesting depth
services = inj.get_all_by_type(Service)
```

## Running tests

```bash
pip install pytest
pytest tests/
```

## Build & publish

```bash
bumpver update --patch   # or --minor / --major
python -m build
twine upload dist/*
```

## License

MIT — Colageo Mirko <mirko.colageo@gmail.com>
