Skip to content

Repository files navigation

Python Simple IoC - Dependency Injection Container

CIPython 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: trueservices:
# Database connectiondatabase:
class: myapp.database.Databasearguments: ["%database_url%"]# User repository with injected databaseuser_repository:
class: myapp.repositories.UserRepositoryarguments: ["@database"]# User service with injected repositoryuser_service:
class: myapp.services.UserServicearguments: ["@user_repository"]calls:
- [set_debug, ["%debug_mode%"]]
  1. Use the container in your application:
importioc# Build container from configurationcontainer=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 injectedusers=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 injectionemail_service:
class: myapp.EmailServicearguments: ["@mailer", "%sender_email%"]# Method calls after constructionlogger:
class: logging.Loggerarguments: ["myapp"]calls:
- [setLevel, ["INFO"]]
- [addHandler, ["@file_handler"]]# Weak references (lazy loading)cache_service:
class: myapp.CacheServicearguments: ["#@redis_client"] # Only loaded when needed

Parameters and Environment

parameters:
# String interpolationlog_file: "/var/log/%app_name%.log"# Environment variablessecret_key: "%env(SECRET_KEY)%"# Default valuesredis_url: "%env(REDIS_URL):redis://localhost:6379%"

🧪 Testing Made Easy

With dependency injection, testing becomes straightforward:

importunittestfromunittest.mockimportMockclassTestUserService(unittest.TestCase):
deftest_create_user(self):
# Mock the repositorymock_repo=Mock()
mock_repo.save.return_value=True# Inject the mockuser_service=UserService(mock_repo)
# Test with confidenceresult=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

Stars

24 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages