AthenaeumAthenaeum
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
Packages
  • next
  • current
  • v9.x
  • v8.x
  • v7.x
  • v6.x
  • v5.x
  • v4.x
  • v3.x
  • v2.x
  • v1.x
Changelog
GitHub
  • Version 10.x

    • Release Notes
    • Upgrade Guide
    • New to this...
    • Contribution Guide
    • Security Policy
    • Code of Conduct
    • Origin
  • ACL

    • Introduction
    • How to install
    • Setup
    • Permissions
    • Roles
    • Users
    • Cached Permissions
  • Antivirus

    • Introduction
    • How to install
    • Setup
    • How to use
    • Scanners

      • Introduction
      • ClamAV
      • Null
      • Custom
    • Events
    • PSR
  • Audit

    • Audit
    • How to install
    • Setup
    • Recording
    • Events
    • Formatting
  • Auth

    • Introduction
    • How to install
    • Fortify

      • Prerequisites
      • Exceptions

        • Failed Login Attempt
        • Password Reset Link Failure
      • Responses

        • Failed Password Reset Link
  • Circuits

    • Circuits
    • How to install
    • Setup
    • Usage
    • Events
  • Collections

    • Collections
    • How to install
    • Summation

      • Summation Collection
      • Items Processor
  • Config

    • Configuration Loader
    • How to install
    • Setup
    • Load Configuration Files
    • Custom File Parsers
  • Console

    • Command and Schedule Registration
    • How to install
    • Setup
    • Commands
    • Schedules
  • Container

    • IoC Service Container
    • How to install
    • Container
    • List Resolver
  • Core

    • Athenaeum Core Application
    • How to install
    • Setup
    • Usage

      • Configuration
      • Service Providers
      • Service Container
      • Events
      • Caching
      • Logging
      • Console
      • Task Scheduling
      • Exception Handling
      • Extending Core Application
      • Testing
  • Database

    • Introduction
    • How to install
    • Models

      • Instantiatable
      • Sluggable
    • Query

      • Criteria (Query Filter)
  • Dto

    • Data Transfer Object (DTO)
    • How to install
    • How to use
  • ETags

    • Introduction
    • How to install
    • Setup
    • ETags usage

      • How to use
      • Generators

        • Default Generator
        • Custom Generator
      • Eloquent Models
    • Http Request Preconditions

      • Introduction
      • Resource Context
      • Preconditions
      • Actions
      • RFC 9110

        • If-Match
        • If-Unmodified-Since
        • If-None-Match
        • If-Modified-Since
        • If-Range
      • Extensions

        • Introduction
        • Range
      • Range Validator
      • Download Stream
    • Macros
  • Events

    • Register Listeners and Subscribers
    • How to install
    • Setup
    • Listeners
    • Subscribers
  • Filters

    • Search Filter Utilities
    • Prerequisites
    • How to install
    • Setup
    • Processor
    • Filters Builder
    • Predefined Resources

      • Search Processor
      • Sorting Processor
      • Constraints Processor
      • Matching Processor
    • Tip: Create a base builder
  • Flysystem

    • Introduction
    • Database Adapter

      • Introduction
      • How to install
      • Setup
      • Data Deduplication
      • MIME-Type Detection
  • Http

    • Api

      • Http API
      • How to install
      • Setup
      • Resources

        • Introduction
        • Timestamps
        • Self-Link
        • Relations
        • Caching
        • Registrar
      • Requests

        • Introduction
        • List Resources
        • List Deleted
        • Show Resource
        • Create Resource
        • Update Resource
        • Delete Resource
        • List Related
        • Process Multiple Resources
        • Helpers
      • Middleware

        • Introduction
        • Request Must Be Json
        • Capture Fields To Select
        • Remove Response Payload
    • Clients

      • Http Clients
      • How to install
      • Setup
      • Basic Usage
      • Available Methods

        • Fluent Api
        • Protocol Version
        • Base Uri
        • Http Method and Uri
        • Headers
        • Accept & Content-Type
        • Authentication
        • Http Query
        • Payload Format
        • Payload
        • Attachments
        • Cookies
        • Response Expectations
        • Middleware
        • Conditions
        • Criteria
        • Redirects
        • Timeout
        • Debugging
        • Logging
        • Driver Options
        • Driver
      • Http Query Builder

        • Introduction
        • Select
        • Where
        • Dates
        • Include
        • Pagination
        • Sorting
        • Raw Expressions
        • Custom Grammar
    • Cookies

      • Http Cookies
      • How to install
      • Usage
    • Messages

      • Http Messages
      • How to install
      • Serializers
  • Maintenance

    • Modes

      • Maintenance Modes
      • How to install
      • Setup
      • Basic Usage
      • Available Drivers
  • Mime Types

    • MIME-Types
    • How to install
    • Setup
    • Usage
    • Drivers

      • Available Drivers
      • File Info
  • Properties

    • Properties Overload
    • How to install
    • Usage
    • Naming Convention
    • Properties Visibility
  • Redmine

    • Redmine Api Client
    • How to install
    • Setup
    • General Usage

      • Supported Operations
      • Fetch list of resources
      • Find
      • Fetch
      • Create new record
      • Update existing record
      • Delete existing record
      • Relations
    • Available Resources

      • Predefined Resources
      • Attachments
      • Enumerations
      • Issue Relations
      • Users
      • User Groups
      • Roles
      • Project Memberships
      • Versions (Milestones)
      • Issue Categories
      • Trackers
  • Service

    • Service Registrar
    • How to install
    • How to use
  • Streams

    • Streams
    • How to install
    • Setup
    • How to use

      • Introduction
      • Open and Close
      • Raw Resource
      • Seeking
      • Reading
      • Writing
      • Size
      • Truncate
      • Sync
      • Flush
      • Hash
      • MIME-Type
      • Filename
      • Output
      • Locking
      • Transactions
      • Meta
      • Misc
  • Support

    • Introduction
    • How to install
    • Laravel Aware-of Helpers

      • How to use
      • Enforce Via Interface
      • Custom Default
      • Pros and Cons
      • Available Helpers
    • Env File
    • Aware-of Properties

      • Generator
    • Live Templates
  • Testing

    • Introduction
    • How to install
    • Test Cases
    • Testing Aware-of Helpers
  • Translation

    • Introduction
    • How to install
    • Exporters

      • Introduction
      • Setup
      • How to use
      • Drivers

        • Introduction
        • Array
        • Lang.js (Array)
        • Lang.js (JSON)
        • Cache
  • Utils

    • Introduction
    • How to install
    • Array
    • Duration
    • Json
    • Math
    • Memory
    • Method Helper
    • Invoker
    • Populatable
    • String
    • Version
  • Validation

    • Introduction
    • How to install
    • Setup
    • Rules

      • Alpha-Dash-Dot
      • Date Format
      • Semantic Version

Service Container

The Core Application is essentially an extended version of Laravel's Service Container. It works exactly as you are used to, in your Laravel projects. This chapter only briefly highlights some of it's major features. For more saturated examples and information on how to use the Service Container, please review Laravel's documentation.

  • Bindings
    • When no interfaces are available
    • Aliases
    • Singleton Bindings
  • Resolving
    • Using the App Facade
    • Using the IoCFacade
    • Inside your Classes
    • Alternative

Bindings

Inside your Service Provider's register() method, you can use the bind() method to register a binding.

<?php

use Acme\Contracts\Weather\Temperature\Measurement as MeasurementInterface;
use Acme\Weather\Temperature\Measurement;
use Illuminate\Support\ServiceProvider;

class WeatherServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(MeasurementInterface::class, function($app){
            return new Measurement();
        });
    }
}

When no interfaces are available

The Service Container does not explicitly require you to state an interface's class path, as the "abstract" identifier for your binding. You can use a regular string value that you wish, as long as it is unique. Depending on just how "legacy" your application is, this can come very handy for you, should you wish to redesign or refactor certain logic.

$this->app->bind('weather-measurement', function($app){
    return new Measurement();
});

Aliases

Another helpful feature of the Service Container, is the ability to create aliases for your bindings. This will allow you to resolve a bound instance, via both an interface's class path or your assigned alias.

$this->app->bind(MeasurementInterface::class, function($app){
    return new Measurement();
});

// "weather-measurement" alias for MeasurementInterface::class
$this->app->alias(MeasurementInterface::class, 'weather-measurement'); 

Singleton Bindings

To bind a single instance, use the singleton() method.

<?php

use Acme\Contracts\Weather\Station;
use Acme\Weather\Stations\LondonWeatherGateway;
use Illuminate\Support\ServiceProvider;

class WeatherServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(Station::class, function($app){
            return new LondonWeatherGateway();
        });
    }
}

Resolving

To resolve a binding, use the make() method on the application instance. Given the above shown examples, imagine that you are somewhere inside your legacy application. To obtain (resolve) your desired bound components, use your $app.

<?php

use Acme\Contracts\Weather\Station;

// ... somewhere inside your custom application

$weatherStation = $app->make(Station::class);

The above example assumes that you are within your entry-point(s), e.g. your index.php, and have direct access to your $app. This might not always be the case for you. In the next few sections, different approaches are explored.

Using the App Facade

You can also resolve your bindings, by using Laravel's App Facade. This Facade provides access to your application instance, as long as your application is running. Such can be useful, in situations where you might not have direct access to your $app.

<?php

use Acme\Contracts\Weather\Station;
use Illuminate\Support\Facades\App;

// ... somewhere inside your custom application

$weatherStation = App::make(Station::class);

Caution

Depending upon how you use Facades, they can either help you to get the job done or become a hindrance. You should take some time to read about their conceptual benefits and limitations.

Using the IoCFacade

The IoCFacade is a custom Facade, which also provides access to your application instance. Just like Laravel's App facade, it too offers the make() method. In addition, it also comes with a tryMake() method, which does not fail, in case that a binding could not be resolved. When a binding cannot be resolved, it returns a default value that you can specify.

<?php

use Acme\Contracts\Weather\Station;
use Acme\Weather\Stations\NullStation;
use Aedart\Support\Facades\IoCFacade;

// ... somewhere inside your custom application

// Either resolves "station" binding or returns a default value.
$weatherStation = IoCFacade::tryMake(Station::class, function(){
    return new NullStation();
});

For more information, please review the source code of IoCFacade.

Inside your Classes

Arguably, when situated inside a class, it is considered best practice to rely on dependency injection, rather than using Facades. Given that you have a component with one or more dependencies, you should type-hint them in the component's constructor. Imagine the following component:

<?php

use Acme\Contracts\Weather\Station;

class WeatherController
{
    protected Station $weatherStation;

    public function __construct(Station $weatherStation)
    {
        $this->weatherStation = $weatherStation;
    }
}

When you need to resolve it's dependencies, use the make() method.

<?php

// Constructor dependencies are automatically resolved.
$controller = $app->make(WeatherController::class);

Alternative

Another approach to resolving you bindings, is by making use of Aware-of Helpers. These helpers are basically "getters and setters" that come with a default value. Consider the following example, where a "Weather Station Aware of" helper is available.

<?php

use Acme\Weather\Stations\Traits\StationTrait;
use Psr\Http\Message\ResponseInterface;

class WeatherController
{
    use StationTrait;

    public function index() : ResponseInterface
    {
        // A default station binding resolved from the Service Container.
        $weatherStation = $this->getStation();
    
        // ... remaining not shown ...
    }
}

The implementation of a "Weather Station Aware of" helper, could look similar to the following example:

<?php

namespace Acme\Weather\Stations\Traits;

use Acme\Contracts\Weather\Station;
use Aedart\Support\Facades\IoCFacade;

trait StationTrait
{
    protected Station|null $station = null;

    public function setStation(Station|null $station): static
    {
        $this->station = $station;
        
        return $this;
    }
    
    public function getStation(): Station|null
    {
        if( ! $this->hasStation()){
            $this->setStation($this->getDefaultStation());
        }
        return $this->station;
    }
    
    public function hasStation(): bool
    {
        return isset($this->station);
    }
    
    public function getDefaultStation(): Station|null
    {
        return IoCFacade::tryMake(Station::class);
    }
}

The benefit of using an "Aware-of" Helper approach, is that your component(s) can "lazy" resolve their dependencies. Furthermore, you always have the possibility to overwrite its methods, meaning that a different implementation could be returned as a default, should you require such.

In any case, you have the freedom to choose how, if at all, you wish to resolve dependencies in your custom application.

Edit page
Last Updated: 31/01/2026, 15:22
Contributors: Alin Eugen Deac, alin, aedart
Prev
Service Providers
Next
Events