Skip to main content

Hook Management

Overview

Hook management in the DomainFlow Container allows you to register custom callbacks (hooks) that execute before and after a service is resolved. This feature lets you inject custom logic—such as logging, parameter modification, or additional configuration—into the dependency resolution process.


Key Concepts

Before Resolve Hooks:

These hooks execute immediately before a service is built. They allow you to perform tasks like logging the service identifier or altering instantiation parameters.

After Resolve Hooks:

These hooks execute after a service has been instantiated. They can be used to modify the resolved instance or perform further configuration before it is returned.

Hook Registration:

The container provides two methods for hook registration:

MethodSignatureDescription
addBeforeResolveaddBeforeResolve(callable $hook): voidRegisters a hook to execute before service resolution.
addAfterResolveaddAfterResolve(callable $hook): voidRegisters a hook to execute after service resolution.

Implementation Details

The container uses a dedicated trait (HookManagerTrait) to manage hooks. This trait maintains two internal arrays:

  • $beforeResolveHooks: An array of callbacks executed before a service is resolved.
  • $afterResolveHooks: An array of callbacks executed after a service is resolved.

When a service is requested:

  1. The container iterates over the before resolve hooks, executing each with the service identifier and any additional parameters.
  2. The service is then built.
  3. Finally, the container processes the after resolve hooks, which can modify or replace the resolved instance.

Example Usage

Below is an example that demonstrates how to register and use hooks within the container:

// Create the container instance.
$container = new Container();

// Register a before resolve hook to log the service identifier before instantiation.
$container->addBeforeResolve(function (string $abstract, array $parameters) {
echo "Resolving service: {$abstract}\n";
});

// Register an after resolve hook to modify the resolved instance.
$container->addAfterResolve(function (object $instance, string $abstract, array $parameters): ?object {
// If the resolved service is an instance of SomeService, set a configuration flag.
if ($instance instanceof SomeService) {
$instance->configured = true;
}
// Return the modified instance (or null to keep the original).
return $instance;
});

// Bind a sample service.
$container->bind(SomeService::class, SomeService::class);

// Resolving the service triggers both hooks.
$service = $container->get(SomeService::class);

// The output includes the before resolve log, and the service instance is modified by the after resolve hook.

In this example:

  • The before resolve hook logs the service identifier each time a service is about to be instantiated.
  • The after resolve hook checks if the resolved instance is of a certain type and adjusts its configuration accordingly.

Benefits

  • Customization:
    Hooks allow you to inject custom behavior into the dependency resolution process without altering the core container logic.

  • Separation of Concerns:
    By isolating cross-cutting concerns (such as logging or additional configuration) into hooks, your service classes remain focused on their primary responsibilities.

  • Flexibility:
    Hooks can modify parameters, adjust the resolved instance, or even replace it entirely, offering high flexibility in managing service lifecycles.


Summary

Hook management in the DomainFlow Container enhances the dependency resolution process by enabling the execution of custom logic both before and after a service is built. This feature not only improves modularity by separating cross-cutting concerns but also provides advanced customization options to tailor the behavior of your application’s service resolution pipeline.