Skip to content
This repository has been archived by the owner on Mar 28, 2021. It is now read-only.
/ services Public archive

A services layer written in PHP for Dependency Injection

License

Notifications You must be signed in to change notification settings

ulrack/services

Repository files navigation

DEPRECATION NOTICE: this package has been moved and improved at grizz-it/services

Build Status

Ulrack Services

This package contains a services implementation. These services can be configured for a project to create a configured depency injection layer. The services are ran through a compiler to create workable data for the factories. The factories are used to retrieve assembled objects for the project. Both the compiler and factory can be extended by creating compiler extensions and factory extensions. On top of that, existing compilers and factories can be extended and altered with hooks.

Installation

To install the package run the following command:

composer require ulrack/services

Usage

Registry

To start, the ServiceRegistry needs to be created. The ServiceRegistry is the object on which all service definitions are registered, before they are compiled. To create the ServiceRegistry use the following snippet:

<?php

use Ulrack\Services\Component\Registry\ServiceRegistry;

$serviceRegistry = new ServiceRegistry();

The service definitions can then be registered with the add method. See the files in configuration/schema to see everything that can be registered out of the box.

<?php

use GrizzIt\Validator\Component\Logical\AlwaysValidator;

$serviceRegistry->add(
    'services',
    'foo',
    [
        'class' => AlwaysValidator::class,
        'parameters' => [
            'alwaysBool' => true
        ]
    ]
);

Compiler

Then to create the compiler use the following snippet:

<?php

use GrizzIt\ObjectFactory\Component\Analyser\ClassAnalyser;
use GrizzIt\ObjectFactory\Factory\ObjectFactory;
use Ulrack\Services\Component\Compiler\ServiceCompiler;
use GrizzIt\Storage\Component\ObjectStorage;
use GrizzIt\ObjectFactory\Component\Reflector\MethodReflector;

// The services storage in this example only exists during the execution.
// Use an alternative implementation of the StorageInterface to keep the compiled services.
$serviceStorage = new ObjectStorage();

$analysisStorage = new ObjectStorage();

$methodReflector = new MethodReflector();

$classAnalyser = new ClassAnalyser(
    $analysisStorage,
    $methodReflector
);

$objectFactory = new ObjectFactory($classAnalyser);

$serviceCompiler = new ServiceCompiler(
    $serviceRegistry,
    $serviceStorage,
    $objectFactory
);

Compiler extensions

The compiler is used to reformat all defined code to operate faster in the factories later on. In order to add logic to the compiler, extensions need to be added. To support services, the ServicesCompiler can be used. Extensions are required to implement the AbstractServiceCompilerExtension.

If the services are already in an optimal state, the PassThroughCompiler can also be chosen.

To add the ServicesCompiler, use the following snippet:

<?php

use Ulrack\Services\Component\Compiler\ServicesCompiler;

$serviceCompiler->addExtension(
    // This will be the key which is used in the service definitions for services.
    'services',
    ServicesCompiler::class,
    // This is the sort order of the extension, it is used to determine the order of execution.
    0,
    // Optionaly a validator implementing the ValidatorInterface can be provided here
    null,
    // Parameters can be provided to the extension here.
    []
);

Compiler hooks

To add a hook to the compiler the following snippet can be used:

<?php

$serviceCompiler->addHook(
    // Note that the key must the same as the the compiler which needs to be hooked into.
    'services',
    MyHook::class,
    // The sort order to determine the order of execution.
    0,
    // Optional parameters for the hook.
    []
);

The hooks are required to implement the AbstractServiceCompilerHook.

Creating the factory

Once everything is configured for the compiler, the factory can be created in a similar way.

<?php

use Ulrack\Services\Factory\ServiceFactory;

$serviceFactory = new ServiceFactory(
    // The previously configured service compiler.
    $serviceCompiler,
    $objectFactory,
    $classAnalyser,
    $methodReflector
);

Factory extensions

Factory extensions must implement the AbstractServiceFactoryExtension. To add the services factory use the following snippet:

<?php

use Ulrack\Services\Factory\Extension\ServicesFactory;

$serviceFactory->addExtension(
    // The key on which services are registered.
    'services',
    ServicesFactory::class,
    // Optional parameters.
    []
);

Factory hooks

Adding a factory hook is similar to factory extension. It must implement the AbstractServiceFactoryHook. Then to add the hook, use the following snippet:

<?php

$serviceFactory->addHook(
    // The key on which services are registered.
    'services',
    MyHook::class,
    // The sort order, used for the order of execution.
    0,
    // A set of optional parameters for the hook.
    []
);

Using the factory

After everything is configured the factory can be used to create an instance of the declared service, or retrieve a certain configured value. To do so invoke the create method with the reference to the service declaration.

<?php

// The key is a combination of the scope of the required service and the name of the service.
$serviceFactory->create('services.foo')

This will return whatever is registered on foo.

Example

To see a full example, see the example directory. Run the following commands in the root directory to be able to execute the example:

composer require ulrack/json-schema
php example/example.php

Change log

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING and CODE_OF_CONDUCT for details.

MIT License

Copyright (c) GrizzIT

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.