> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tasteful.heka.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-008: Flavor Architecture Modernization

> Migration from class attributes to constructor-based initialization for improved dependency injection and testing

# ADR-008: Flavor Architecture Modernization

## Context

The framework's flavor architecture used class attributes to define components, which prevented dependency injection, made testing difficult, and couldn't leverage the new graph-based dependency resolution system.

## Decision

**Migrated from class attribute-based component definition to constructor-based initialization** for all flavor components, enabling proper dependency injection and improved testability.

### Key Changes

* **Constructor-Based Flavor Definition**: Components defined through constructor parameters
* **Dependency Injection Integration**: Components receive dependencies through constructors
* **Base Class Separation**: Dedicated base classes for controllers, services, repositories, and config
* **Graph-Based Resolution**: Full compatibility with automatic dependency resolution

### Migration Pattern

**Old Class Attribute Pattern:**

```python theme={null}
class UserFlavor(BaseFlavor):
    controller = UserController
    services = [UserService]
    repositories = [UserRepository]

class UserController(BaseController):
    prefix = "/users"
    
    def get_user(self, user_id: int):
        user_service = get_service(UserService)  # Anti-pattern
        return user_service.get_user(user_id)
```

**New Constructor Pattern:**

```python theme={null}
class UserFlavor(BaseFlavor):
    def __init__(self):
        super().__init__(
            controller=UserController,
            services=[UserService],
            repositories=[UserRepository],
            config=UserConfig
        )

class UserController(BaseController):
    def __init__(self, user_service: UserService):
        super().__init__(prefix="/users", tags=["users"])
        self.user_service = user_service
    
    @Get("/{user_id}")
    def get_user(self, user_id: int):
        return self.user_service.get_user(user_id)
```

## Consequences

### Positive

* Proper dependency injection through constructors
* Improved testability with easy mocking
* Configuration injection into specific components
* Runtime flexibility for conditional components
* Type safety with constructor parameters
* Compatibility with graph-based dependency resolution

### Negative

* Migration effort for existing flavors
* Slightly more verbose component definitions
* Learning curve for dependency injection concepts
* Breaking change from class attribute pattern

## Usage Example

```python theme={null}
class UserService(BaseService):
    def __init__(self, user_repository: UserRepository, config: UserConfig):
        super().__init__()
        self.user_repository = user_repository
        self.config = config

class UserFlavor(BaseFlavor):
    def __init__(self):
        super().__init__(
            controller=UserController,
            services=[UserService],
            repositories=[UserRepository],
            config=UserConfig
        )
```

Components now receive dependencies through constructors, enabling clean architecture and easy testing.
