CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-rodi

Implementation of dependency injection for Python 3

Overall
score

92%

Overview
Eval results
Files

aliases-names.mddocs/

Aliases and Names

Convention-based service registration and resolution using string names and aliases instead of type annotations. This approach enables flexible service registration patterns and runtime service resolution by name.

Capabilities

Single Alias Registration

Register a single name-to-type mapping for convention-based service resolution.

def add_alias(self, name: str, desired_type: Type) -> Container:
    """
    Add a single alias mapping name to type.
    
    Args:
        name: String name/alias for the service
        desired_type: Type to associate with the name
        
    Returns:
        Container instance for method chaining
        
    Raises:
        AliasAlreadyDefined: If alias already exists
    """

Multiple Aliases Registration

Register multiple name-to-type mappings at once using a dictionary.

def add_aliases(self, values: AliasesTypeHint) -> Container:
    """
    Add multiple alias mappings from a dictionary.
    
    Args:
        values: Dictionary mapping names to types
        
    Returns:
        Container instance for method chaining
        
    Raises:
        AliasAlreadyDefined: If any alias already exists
    """

Single Alias Setting (Override)

Set a single alias with optional override capability for existing aliases.

def set_alias(self, name: str, desired_type: Type, override: bool = False) -> Container:
    """
    Set a single alias mapping, optionally overriding existing aliases.
    
    Args:
        name: String name/alias for the service
        desired_type: Type to associate with the name
        override: If True, allows overriding existing aliases
        
    Returns:
        Container instance for method chaining
        
    Raises:
        AliasAlreadyDefined: If alias exists and override is False
    """

Multiple Aliases Setting (Override)

Set multiple aliases with optional override capability.

def set_aliases(self, values: AliasesTypeHint, override: bool = False) -> Container:
    """
    Set multiple alias mappings, optionally overriding existing aliases.
    
    Args:
        values: Dictionary mapping names to types
        override: If True, allows overriding existing aliases
        
    Returns:
        Container instance for method chaining
        
    Raises:
        AliasAlreadyDefined: If any alias exists and override is False
    """

Types and Utilities

Aliases Type Hint

Type definition for alias dictionaries mapping string names to types.

AliasesTypeHint = Dict[str, Type]

Standard Parameter Name Conversion

Utility function to convert class names to standard parameter names following Python conventions.

def to_standard_param_name(name) -> str:
    """
    Convert class names to standard parameter names.
    
    Args:
        name: Class name to convert
        
    Returns:
        Converted parameter name (e.g., "UserService" -> "user_service")
    """

Usage Patterns

Convention-based Registration

Register services using naming conventions instead of explicit type mappings:

# Register services with conventional names
container.register(UserService)
container.register(DatabaseService)
container.register(EmailService)

# Add aliases for convention-based resolution
aliases = {
    "user_service": UserService,
    "database_service": DatabaseService,
    "email_service": EmailService
}
container.add_aliases(aliases)

# Resolve by name
user_service = container.resolve("user_service")

Parameter Name Resolution

Use aliases to enable parameter name-based dependency injection:

def business_method(user_service, email_service, database_service):
    # Method automatically gets services by parameter names
    pass

# Services will be resolved by matching parameter names to aliases
services.exec(business_method)

Configuration-driven Registration

Use aliases for configuration-driven service registration:

# Configuration defines service mappings
service_config = {
    "user_repository": "SqlUserRepository",
    "email_provider": "SmtpEmailService",
    "cache_provider": "RedisCache"
}

# Register services based on configuration
for alias, service_name in service_config.items():
    service_type = globals()[service_name]  # Get type by name
    container.register(service_type)
    container.add_alias(alias, service_type)

Multi-environment Configuration

Use aliases to switch between different implementations:

# Development environment
dev_aliases = {
    "database": MockDatabase,
    "email_service": ConsoleEmailService,
    "storage": LocalFileStorage
}

# Production environment  
prod_aliases = {
    "database": PostgreSQLDatabase,
    "email_service": SmtpEmailService,
    "storage": S3Storage
}

# Register based on environment
if environment == "development":
    container.set_aliases(dev_aliases, override=True)
else:
    container.set_aliases(prod_aliases, override=True)

Runtime Service Resolution

Resolve services dynamically at runtime using string names:

def get_service_by_name(service_name: str):
    """Dynamically resolve service by name."""
    return services.get(service_name)

# Usage
service_name = user_input  # From user, config, etc.
service = get_service_by_name(service_name)

Plugin Architecture

Use aliases to support plugin-based architectures:

# Plugin registration
def register_plugin(plugin_name: str, plugin_class: Type):
    container.register(plugin_class)
    container.add_alias(f"plugin_{plugin_name}", plugin_class)

# Plugin loading
def load_plugin(plugin_name: str):
    alias = f"plugin_{plugin_name}"
    if alias in container:
        return container.resolve(alias)
    else:
        raise ValueError(f"Plugin '{plugin_name}' not found")

Exception Handling

Alias-related exceptions that may be raised during alias operations:

class AliasAlreadyDefined(DIException):
    """Raised when attempting to add an alias that already exists."""

class AliasConfigurationError(DIException):
    """Raised when an alias references an unconfigured type."""

These exceptions help identify configuration issues:

try:
    container.add_alias("existing_alias", NewService)
except AliasAlreadyDefined:
    # Handle duplicate alias
    container.set_alias("existing_alias", NewService, override=True)

try:
    service = container.resolve("unknown_alias")
except AliasConfigurationError:
    # Handle missing alias configuration
    logging.error("Service alias not configured")

Install with Tessl CLI

npx tessl i tessl/pypi-rodi

docs

aliases-names.md

container-configuration.md

factory-registration.md

index.md

scoped-services.md

service-resolution.md

tile.json