PHPackages                             gacela-project/container - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PSR &amp; Standards](/categories/psr-standards)
4. /
5. gacela-project/container

ActiveLibrary[PSR &amp; Standards](/categories/psr-standards)

gacela-project/container
========================

A minimalistic container dependency resolver

0.8.1(4w ago)11147.7k↑1282.7%2MITPHPPHP &gt;=8.1CI passing

Since Apr 11Pushed 4w ago1 watchersCompare

[ Source](https://github.com/gacela-project/container)[ Packagist](https://packagist.org/packages/gacela-project/container)[ Docs](https://gacela-project.com)[ Fund](https://chemaclass.com/sponsor)[ RSS](/packages/gacela-project-container/feed)WikiDiscussions main Synced yesterday

READMEChangelog (9)Dependencies (14)Versions (12)Used By (2)

Gacela Container
================

[](#gacela-container)

 [ ![GitHub Build Status](https://github.com/gacela-project/container/workflows/CI/badge.svg) ](https://github.com/gacela-project/container/actions) [ ![Scrutinizer Code Quality](https://camo.githubusercontent.com/fb2f7f0489256498d9835852e33eebf0efc2cc715905a68ca1d3d05feb9ff2b1/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f676163656c612d70726f6a6563742f636f6e7461696e65722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d61696e) ](https://scrutinizer-ci.com/g/gacela-project/container/?branch=main) [ ![Scrutinizer Code Coverage](https://camo.githubusercontent.com/7e7f422a99b6fa8bb2c616b87d6d49698992e582afc3540750a44ad87c9bb493/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f676163656c612d70726f6a6563742f636f6e7461696e65722f6261646765732f636f7665726167652e706e673f623d6d61696e) ](https://scrutinizer-ci.com/g/gacela-project/container/?branch=main) [ ![Psalm Type-coverage Status](https://camo.githubusercontent.com/a6654b118fb31475cfbcaec921a40cddf3d14726de40add51cb04fbefd6de103/68747470733a2f2f73686570686572642e6465762f6769746875622f676163656c612d70726f6a6563742f636f6e7461696e65722f636f7665726167652e737667) ](https://shepherd.dev/github/gacela-project/container) [ ![MIT Software License](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667) ](https://github.com/gacela-project/container/blob/master/LICENSE)

A minimalistic, PSR-11 compliant dependency injection container with automatic constructor injection and zero configuration.

Features
--------

[](#features)

- 🚀 **Zero Configuration**: Automatic constructor injection without verbose setup
- 🔄 **Circular Dependency Detection**: Clear error messages when dependencies form a loop
- 📦 **PSR-11 Compliant**: Standard container interface for interoperability
- ⚡ **Performance Optimized**: Built-in caching and warmup capabilities
- 🔍 **Introspection**: Debug and inspect container state easily
- 🎯 **Type Safe**: Requires type hints for reliable dependency resolution
- 🏷️ **PHP 8 Attributes**: Declarative configuration with #\[Inject\], #\[Singleton\], and #\[Factory\]

Installation
------------

[](#installation)

```
composer require gacela-project/container
```

Quick Start
-----------

[](#quick-start)

### Basic Usage

[](#basic-usage)

```
use Gacela\Container\Container;

// Simple auto-wiring
$container = new Container();
$instance = $container->get(YourClass::class);
```

### With Bindings

[](#with-bindings)

Map interfaces to concrete implementations:

```
$bindings = [
    LoggerInterface::class => FileLogger::class,
    CacheInterface::class => new RedisCache('localhost'),
    ConfigInterface::class => fn() => loadConfig(),
];

$container = new Container($bindings);
$logger = $container->get(LoggerInterface::class); // Returns FileLogger
```

### Contextual Bindings

[](#contextual-bindings)

Different implementations based on which class needs them:

```
// UserController gets FileLogger, AdminController gets DatabaseLogger
$container->when(UserController::class)
    ->needs(LoggerInterface::class)
    ->give(FileLogger::class);

$container->when(AdminController::class)
    ->needs(LoggerInterface::class)
    ->give(DatabaseLogger::class);

// Multiple classes can share the same contextual binding
$container->when([ServiceA::class, ServiceB::class])
    ->needs(CacheInterface::class)
    ->give(RedisCache::class);
```

### PHP 8 Attributes

[](#php-8-attributes)

Use attributes for declarative dependency configuration:

#### \#\[Inject\] - Specify Implementation

[](#inject---specify-implementation)

Override type hints to inject specific implementations:

```
use Gacela\Container\Attribute\Inject;

class NotificationService {
    public function __construct(
        #[Inject(EmailLogger::class)]
        private LoggerInterface $logger,
    ) {}
}

// EmailLogger will be injected even if LoggerInterface is bound to FileLogger
$service = $container->get(NotificationService::class);
```

#### \#\[Singleton\] - Single Instance

[](#singleton---single-instance)

Mark a class to be instantiated only once:

```
use Gacela\Container\Attribute\Singleton;

#[Singleton]
class DatabaseConnection {
    public function __construct(private string $dsn) {}
}

$conn1 = $container->get(DatabaseConnection::class);
$conn2 = $container->get(DatabaseConnection::class);
// $conn1 === $conn2 (same instance)
```

#### \#\[Factory\] - New Instances

[](#factory---new-instances)

Always create fresh instances:

```
use Gacela\Container\Attribute\Factory;

#[Factory]
class RequestContext {
    public function __construct(private LoggerInterface $logger) {}
}

$ctx1 = $container->get(RequestContext::class);
$ctx2 = $container->get(RequestContext::class);
// $ctx1 !== $ctx2 (different instances)
```

**Performance Note:** Attribute checks are cached internally, so repeated instantiations of the same class avoid expensive reflection operations, providing 15-20% performance improvement.

How It Works
------------

[](#how-it-works)

The container automatically resolves dependencies based on type hints:

- **Primitive types**: Uses default values (must be provided)
- **Classes**: Instantiates and resolves dependencies recursively
- **Interfaces**: Resolves using bindings defined in the container

### Example

[](#example)

```
class UserService {
    public function __construct(
        private UserRepository $repository,
        private LoggerInterface $logger,
    ) {}
}

class UserRepository {
    public function __construct(private PDO $pdo) {}
}

// Setup
$bindings = [
    LoggerInterface::class => FileLogger::class,
    PDO::class => new PDO('mysql:host=localhost;dbname=app', 'user', 'pass'),
];

$container = new Container($bindings);

// Auto-resolves UserService -> UserRepository -> PDO
$service = $container->get(UserService::class);
```

Advanced Features
-----------------

[](#advanced-features)

### Factory Services

[](#factory-services)

Create new instances on every call:

```
$factory = $container->factory(fn() => new TempFile());
$container->set('temp_file', $factory);

$file1 = $container->get('temp_file'); // New instance
$file2 = $container->get('temp_file'); // Different instance
```

### Extending Services

[](#extending-services)

Wrap or modify services (even before they're created):

```
$container->set('logger', fn() => new FileLogger('/var/log/app.log'));

$container->extend('logger', function ($logger, $container) {
    return new LoggerDecorator($logger);
});
```

### Protecting Closures

[](#protecting-closures)

Prevent closures from being executed:

```
$closure = fn() => 'Hello World';
$container->set('greeting', $container->protect($closure));

$result = $container->get('greeting'); // Returns the closure itself
```

### Resolving Callables

[](#resolving-callables)

Automatically inject dependencies into any callable:

```
$result = $container->resolve(function (LoggerInterface $logger, CacheInterface $cache) {
    $logger->info('Cache cleared');
    return $cache->clear();
});
```

### Service Introspection

[](#service-introspection)

Debug and inspect container state:

```
// Get all registered service IDs
$services = $container->getRegisteredServices();

// Check if service is a factory
if ($container->isFactory('temp_file')) {
    // Returns new instance each time
}

// Check if service is frozen (accessed)
if ($container->isFrozen('logger')) {
    // Cannot be modified anymore
}

// Get all bindings
$bindings = $container->getBindings();

// Get comprehensive statistics
$stats = $container->getStats();
/*
[
    'registered_services' => 42,
    'frozen_services' => 15,
    'factory_services' => 3,
    'bindings' => 8,
    'cached_dependencies' => 25,
    'memory_usage' => '2.34 MB'
]
*/
```

### Performance Optimization

[](#performance-optimization)

Pre-resolve dependencies for faster runtime:

```
// During application bootstrap
$container->warmUp([
    UserService::class,
    OrderService::class,
    PaymentProcessor::class,
]);

// Later requests benefit from cached dependency resolution
$service = $container->get(UserService::class); // Faster!
```

### Service Aliasing

[](#service-aliasing)

Create multiple names for the same service:

```
// Create an alias
$container->alias('db', PDO::class);

// Access via alias or original name
$db1 = $container->get('db');        // Same instance
$db2 = $container->get(PDO::class);  // Same instance

// Alias resolution is cached for optimal performance
```

API Reference
-------------

[](#api-reference)

### Container Methods

[](#container-methods)

MethodDescription`get(string $id): mixed`Retrieve or create a service`has(string $id): bool`Check if service exists`set(string $id, mixed $instance): void`Register a service`remove(string $id): void`Remove a service`resolve(callable $callable): mixed`Execute callable with dependency injection`factory(Closure $instance): Closure`Mark service as factory (new instance each time)`extend(string $id, Closure $instance): Closure`Wrap/modify a service`protect(Closure $instance): Closure`Prevent closure execution`getRegisteredServices(): array`Get all service IDs`isFactory(string $id): bool`Check if service is a factory`isFrozen(string $id): bool`Check if service is frozen`getBindings(): array`Get all bindings`warmUp(array $classNames): void`Pre-resolve dependencies`alias(string $alias, string $id): void`Create an alias for a service (with caching)`getStats(): array`Get container statistics for debugging and performance monitoring`when(string|array $concrete): ContextualBindingBuilder`Define contextual bindings for specific classes### Static Methods

[](#static-methods)

```
// Quick instantiation without container setup
$instance = Container::create(YourClass::class);
```

Best Practices
--------------

[](#best-practices)

### 1. Use Constructor Injection

[](#1-use-constructor-injection)

```
// Good
class UserController {
    public function __construct(
        private UserService $userService,
        private LoggerInterface $logger
    ) {}
}

// Avoid setter injection (not supported)
```

### 2. Always Use Type Hints

[](#2-always-use-type-hints)

```
// Good - type hint required
public function __construct(LoggerInterface $logger) {}

// Bad - will throw exception
public function __construct($logger) {}
```

### 3. Provide Default Values for Scalars

[](#3-provide-default-values-for-scalars)

```
// Good
public function __construct(
    UserRepository $repo,
    int $maxRetries = 3,
    string $env = 'production'
) {}

// Bad - scalars without defaults cannot be resolved
public function __construct(string $apiKey) {} // Exception!
```

### 4. Use Bindings for Interfaces

[](#4-use-bindings-for-interfaces)

```
// Always bind interfaces to implementations
$bindings = [
    LoggerInterface::class => FileLogger::class,
    CacheInterface::class => RedisCache::class,
];
```

### 5. Warm Up in Production

[](#5-warm-up-in-production)

```
// In your bootstrap file
$container->warmUp([
    // List frequently used services
    UserService::class,
    AuthService::class,
    Router::class,
]);
```

Error Handling
--------------

[](#error-handling)

The container provides clear, actionable error messages with helpful suggestions:

### Missing Type Hint

[](#missing-type-hint)

```
No type hint found for parameter '$logger'.
Type hints are required for dependency injection to work properly.

Add a type hint to the parameter, for example:
  public function __construct(YourClass $logger) { ... }

```

### Circular Dependency

[](#circular-dependency)

```
Circular dependency detected: ClassA -> ClassB -> ClassC -> ClassA

This happens when classes depend on each other in a loop.
Consider using setter injection or the factory pattern to break the cycle.

```

### Unresolvable Scalar

[](#unresolvable-scalar)

```
Unable to resolve parameter of type 'string' in 'UserService'.
Scalar types (string, int, float, bool, array) cannot be auto-resolved.

Provide a default value for the parameter:
  public function __construct(string $param = 'default') { ... }

```

### Service Not Found (with suggestions)

[](#service-not-found-with-suggestions)

```
No concrete class was found that implements:
"App\LogerInterface"
Did you forget to bind this interface to a concrete class?

Did you mean one of these?
  - App\LoggerInterface
  - App\Service\LoggerInterface

You might find some help here: https://gacela-project.com/docs/bootstrap/#bindings

```

Requirements
------------

[](#requirements)

- PHP &gt;= 8.1
- PSR-11 Container Interface

Testing
-------

[](#testing)

```
composer test          # Run tests
composer quality       # Run static analysis
composer test-coverage # Generate coverage report
```

Real-World Example
------------------

[](#real-world-example)

See how it's used in the [Gacela Framework](https://github.com/gacela-project/gacela/blob/main/src/Framework/ClassResolver/AbstractClassResolver.php#L142)

License
-------

[](#license)

MIT License. See [LICENSE](LICENSE) file for details.

###  Health Score

53

—

FairBetter than 96% of packages

Maintenance94

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community18

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 84.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~115 days

Recently: every ~224 days

Total

11

Last Release

28d ago

PHP version history (2 changes)0.1.0PHP ^8.0, &lt;8.3

0.6.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/3d166420c6770c5941e10bd68b2d26501eabb432e280d8e6eba0a344bcc1e5ae?d=identicon)[Chemaclass](/maintainers/Chemaclass)

![](https://avatars.githubusercontent.com/u/6381924?v=4)[Jesus Valera Reales](/maintainers/JesusValeraDev)[@JesusValeraDev](https://github.com/JesusValeraDev)

---

Top Contributors

[![Chemaclass](https://avatars.githubusercontent.com/u/5256287?v=4)](https://github.com/Chemaclass "Chemaclass (106 commits)")[![JesusValeraDev](https://avatars.githubusercontent.com/u/6381924?v=4)](https://github.com/JesusValeraDev "JesusValeraDev (17 commits)")[![antonio-gg-dev](https://avatars.githubusercontent.com/u/13595197?v=4)](https://github.com/antonio-gg-dev "antonio-gg-dev (1 commits)")[![khru](https://avatars.githubusercontent.com/u/6353105?v=4)](https://github.com/khru "khru (1 commits)")

---

Tags

containerdependency-resolvergacelaphpresolverphpcontainerresolvergacela

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/gacela-project-container/health.svg)

```
[![Health](https://phpackages.com/badges/gacela-project-container/health.svg)](https://phpackages.com/packages/gacela-project-container)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
