Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP Attributes for Bootloader Methods #1064

Open
butschster opened this issue Jan 18, 2024 · 1 comment
Open

PHP Attributes for Bootloader Methods #1064

butschster opened this issue Jan 18, 2024 · 1 comment

Comments

@butschster
Copy link
Member

Spiral provides an efficient way to bootstrap applications, allowing developers to register container bindings and configure applications effectively. However, this process can be further enhanced by introducing PHP attributes for the bootloader methods.

Motivation

Currently, Spiral utilizes methods such as defineBindings, defineSingletons, init, and boot for container bindings and application configuration. While this approach is functional, PHP attributes can make the process more intuitive and less verbose, improving readability and maintainability.

Proposed PHP Attributes

  1. InitMethod: Used to mark methods that are involved in the initialization process.
  2. BootMethod: Used to mark methods that are part of the bootstrapping sequence.
  3. SingletonMethod: Used to define singleton services within the application.
  4. BindMethod: Used for binding services in the container.

Examples of Usage

1. InitMethod Attribute

Current approach

public function init(EnvironmentInterface $environment, SomeService $service): void 
{
    $envs = [];
    foreach ($environment->getAll() as $key => $value) {
        if (\str_starts_with($key, 'SCANNER_ENV_')) {
            $key = \substr($key, \strlen('SCANNER_ENV_'));
            /** @psalm-suppress InvalidLiteralArgument */
            $envs[$key] = (\is_string($value) && \str_starts_with('$', $value))
                ? $environment->get(\substr($value, 1))
                : $value;
        }
    }

    $this->config->setDefaults(ScannerEnvConfig::CONFIG, $envs);

    $service->boot();
}

Purpose: This attribute is used to mark methods that are involved in the initialization process of the application.

Example:

#[InitMethod]
public function initConfiguration(SomeService $service): void 
{
    // Gather environment variables specific to a module or feature
    $envs = [];
    foreach ($environment->getAll() as $key => $value) {
        if (\str_starts_with($key, 'MY_APP_PREFIX_')) {
            $key = \substr($key, \strlen('MY_APP_PREFIX_'));
            $envs[$key] = $value;
        }
    }

    // Set defaults or configure components based on these variables
    $this->config->setDefaults(MyAppConfig::CONFIG, $envs);
}


#[InitMethod]
public function bootService(EnvironmentInterface $environment): void 
{
    $service->boot();
}

2. BootMethod Attribute

Current approach

public function boot(): void
{
    // ... initialization logic ...
}

Purpose: This attribute designates methods that are part of the application's bootstrapping process.

Example:

#[BootMethod]
public function prepareServices(SomeService $service): void 
{
    // Perform actions necessary to prepare the service for use
    $service->initialize();
    $service->loadData();
    $service->boot();
}


#[BootMethod]
public function someService(): void 
{
    // Perform actions necessary to prepare the service for use ...
}

3. SingletonMethod Attribute

Purpose: Used to define singleton services within the application, ensuring only one instance exists.

Example:

#[SingletonMethod(alias: CacheService::class)]
public function initCacheService(ConfigInterface $config): CacheService 
{
    $cacheConfig = $config->get('cache');
    return new CacheService($cacheConfig);
}

4. BindMethod Attribute

Purpose: Used for defining methods that bind services or implementations to interfaces in the dependency injection container.

Example:

#[BindMethod(LoggerInterface::class)]
public function bindLogger(): LoggerInterface 
{
   return new Logger(...);
}

In summary, these attributes (InitMethod, BootMethod, SingletonMethod, BindMethod) aim to simplify and clarify the definition of methods within the Spiral Framework's bootloader, enhancing readability and maintainability. Each attribute plays a distinct role in organizing the bootstrapping and initialization process of the application.

@lifewcody
Copy link

lifewcody commented Apr 15, 2024

If you're going to have multiple #[BootMethod] I suggest adding a priority ex: #[BootMethod(1)]

But I very much like this idea better

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

2 participants