Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

rande/python-simple-ioc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

143 Commits

Repository files navigation

Python Simple IoC - Dependency Injection Container

CI Python 3.9+ License

A lightweight, Pythonic dependency injection container inspired by Symfony's DependencyInjection component. This library embraces Python's philosophy of simplicity while providing powerful tools for organizing complex applications.

🎯 Why Use Dependency Injection?

Dependency injection isn't just enterprise complexity - it's a Pythonic pattern that promotes:

  • Clear separation of concerns - Each class has a single responsibility
  • Testability - Easy to mock dependencies for unit tests
  • Flexibility - Change implementations without touching existing code
  • Maintainability - Explicit dependencies make code easier to understand

This approach aligns perfectly with Python's zen: "Explicit is better than implicit" and "Readability counts".

πŸš€ Quick Start

Installation

pip install ioc

Basic Usage

  1. Define your services in a services.yml file:
parameters:
 database_url: "sqlite:///app.db"
 debug_mode: true
services:
 # Database connection
 database:
 class: myapp.database.Database
 arguments: ["%database_url%"]
 
 # User repository with injected database
 user_repository:
 class: myapp.repositories.UserRepository
 arguments: ["@database"]
 
 # User service with injected repository
 user_service:
 class: myapp.services.UserService
 arguments: ["@user_repository"]
 calls:
 - [set_debug, ["%debug_mode%"]]
  1. Use the container in your application:
import ioc
# Build container from configuration
container = ioc.build(['services.yml'])
# Get your services - dependencies are automatically resolved!
user_service = container.get('user_service')
# Your service is ready to use with all dependencies injected
users = user_service.get_all_users()

πŸ—οΈ Perfect for Python Projects

This library follows Python best practices:

  • Configuration over code - Define dependencies in YAML, not scattered across your codebase
  • Explicit dependencies - See exactly what each service needs at a glance
  • No magic - Simple, predictable behavior that follows Python conventions
  • Framework agnostic - Works with Flask, Django, FastAPI, or pure Python

πŸ“š Advanced Features

Service Definitions

services:
 # Constructor injection
 email_service:
 class: myapp.EmailService
 arguments: ["@mailer", "%sender_email%"]
 
 # Method calls after construction
 logger:
 class: logging.Logger
 arguments: ["myapp"]
 calls:
 - [setLevel, ["INFO"]]
 - [addHandler, ["@file_handler"]]
 
 # Weak references (lazy loading)
 cache_service:
 class: myapp.CacheService
 arguments: ["#@redis_client"] # Only loaded when needed

Parameters and Environment

parameters:
 # String interpolation
 log_file: "/var/log/%app_name%.log"
 
 # Environment variables
 secret_key: "%env(SECRET_KEY)%"
 
 # Default values
 redis_url: "%env(REDIS_URL):redis://localhost:6379%"

πŸ§ͺ Testing Made Easy

With dependency injection, testing becomes straightforward:

import unittest
from unittest.mock import Mock
class TestUserService(unittest.TestCase):
 def test_create_user(self):
 # Mock the repository
 mock_repo = Mock()
 mock_repo.save.return_value = True
 
 # Inject the mock
 user_service = UserService(mock_repo)
 
 # Test with confidence
 result = user_service.create_user("john@example.com")
 self.assertTrue(result)
 mock_repo.save.assert_called_once()

πŸ“– Learn More

🀝 Contributing

Contributions are welcome! This project follows Python community standards:

  • PEP 8 code style
  • Type hints for better IDE support
  • Comprehensive tests
  • Clear documentation

πŸ“„ License

Licensed under the Apache License 2.0. See LICENSE for details.


"Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex." - The Zen of Python

This library embodies these principles while providing the power and flexibility needed for serious Python applications.

About

A simple Python IOC based on Symfony2 Dependency Component

Resources

License

Stars

Watchers

Forks

Packages

No packages published

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /