Download the PHP package improvframework/service-provisioning without Composer

On this page you can find all versions of the php package improvframework/service-provisioning. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package service-provisioning

Build Status Dependency Status Code Climate Coverage Status

Improv Framework - Service Provisioning

A PSR-11-compatible package intended to ease the organization and loading of container services.

Motivation

A Dependency Injection Container is primarily used to retrieve fully-configured services that are shared througout an application. In order to fetch these services, they must be installed or registered into the Container. This package aims to simplify the registration process.

The Problem

The documentation for many frameworks and containers will illustrate some sort of trivial "Hello World"-esque example. These steups often include something like a container.php, a config.php, or a bootstrap.php, etc, within which all of the example application's services are installed into the shared container. When this file must grow to support slightly more functionality, things can quickly start to get busy. E.g.,

This helps to keep application entrypoints nice and trim, like HTTP front-controllers, CLI scripts, crons, etc.

The example above is trite and a bit naive, but the problem is evident. We have only a few main services configured, with just a couple of domain entities (Blog and User, here). Imagine a much larger application, with several more entities to manage. It also has each service being instantiated with no further operations, whereas many objects often need tweaking or configuration before being returned. Moreover, this container has nothing by way of factories, validators, event dispatchers, loggers, profilers, formatters, authentication services, read/write database, cache storage, etc. It's not difficult to see that "inline" container management becomes unwieldy almost immediately, and practically impossible in all but the smallest of real-world applications.

There are two things occurring in the above example that are required to initialize the container for the script run. First, the services are being defined and configured in container.php. That, in and of itself, does nothing for the running PHP process unless this file is invoked by being included within index.php, causing the loading of the services at that time.

Technically, the "loading" of services into memory is done lazily, but conceptually it occurs here, because the inclusion of the file is necessary for any loading to ever take place. These details are not relevant to the problem space.

The Solution

The Improv Service Provisioning library sets out to resolve the above issues.

ServiceLoaders

The awkward line of $configuration = include('../container.php'); can be abstracted away by introducing a layer whose only responsibility is to "load" any and all services for the application. Conceptually, this may be as simple as replacing the include line with a call to a loader class's method such as loadServices.

We can think of this class or layer as a ServiceLoader in that its job is to "load" the services into the running application.

The benefit to this approach is that the action of loading of services becomes testable, and encapsulates the details about how the loading is happening. Whether it's actually just reading in the same huge container.php file, or leveraging several other files under the hood, it's hidden away and the loading becomes more reusable as a result. Instead of reading in files, it may even call on another layer of classes to define services (seen next). Further, the swapping or mixing of loading strategies becomes possible, without affecting the consuming application.

ServiceProviders

Whether or not we use a ServiceLoader, as described above, using a single file or set of files can still leave us with a complicated mess.

We can avoid this scenario by forming logical groups of associated services into classes of their own. Such a class might be known as a ServiceProvider, in the sense that this separate class provides suites of related services to the application.

The positive consequences of this are similar to those above. Providers encapsulate their speicifc implementation logic and become testable units, as well. They become more legible, compact, and easier to reason about. Providers can even be extracted to packages alongside their services and re-used across applications.

Package Installation

Using Composer (Recommended)

Manual

Each release is available for download from the releases page on Github. Alternatively, you may fork, clone, and build the package. Then, install into the location of your choice.

This package conforms to PSR-4 autoloading standards.

Usage

ServiceLoaderInterace

The interface \Improv\ServiceProvisioning\ServiceLoaderInterface can be used to encapsulate any strategy desired for attaching services to a \Psr\Container\ContainerInterface container. This can be done by implementing the loadServices(ContainerInterface $continer) method of the interface.

As an example, we can look at one such strategy included within this package.

ClassNameServiceLoader

The class \Improv\ServiceProvisioning\Loaders\ClassNameServiceLoader is a concrete implentation of the ServiceLoaderInterface. It takes an array of string class names, instantiates every one, and operates on each using a passed-in callback to attach it to the Container.

The $subject may be operated on, have a method called upon it, or whatever is necessary.

Assuming all classes in the $map are of the same type, they could potentially be type hinted in the callback signature. Similarly, any class with an __invoke method may be passed in as the callable, e.g.:

Using a callback to "invoke" the attachment of the service into the Container means that this implementation of the ServiceLoaderInterface can be used with any other Container library (e.g. Pimple or \League\Container, something custom, etc), bridging a gap between proprietary code and Container.

An example of leveraging class-based Invokers is available below, and the Improv Framework also offers one specifically for integrating with the popular Pimple\Container project.

This library also offers its own brand of service providers, covered next.

ServiceProviderInterface

The \Improv\ServiceProvisioning\ServiceProviderInterface defines a register(ContainerInterface $container) signature.

As pointed out in the sections above, it is often useful to aggregate services (classes that need to be registered into a Container) into logical groupings of related functionality. E.g., adding "User" functionality may require the setting of several services on the container; a controller, some services, a repository, etc. These items could be grouped together in a "ServiceProvider" such that the provider may encapsulate the registration details of all the services related to the "module".

Calling register on the ServiceProvider should install into the Container all services of the module. In this sense, the implementation Provides to the application a suite of Services.

An implementation from our "problem" example, above, may look like:

Tying it Together

It should be noted that the ServiceProviderInterface and the ServiceLoaderInterface (along with its concretions) bundled in this package have no dependencies on one another. The use of one does not require (nor does it preclude) the use of the other.

However, these concepts go hand-in-hand. For projects starting anew or migrating to one or the other, it may make sense to leverage both. For this reason, and because the footprint of each is small, both are provided within this same package. This may change in the future.

ServiceProviderInvoker

Should both interfaces be put to use in the same project and, more, an extension that uses the "callable" approach be used as a Locator, there is one more convenience class provided in this package to bridge the gap between the two.

As stated earlier, the callable $invoker injected into, say, the ClassNameServiceLoader may come in the form of class instead of a lambda. Because the act of installing an Improv ServiceProviderInterface implementation into the Container simply requires calling register on the provider, it is trivial to create a class that does this for us when invoked as a callable. The \Improv\ServiceProvisioning\Invokers\ServiceProviderInvoker class does exactly that.

As such, an updated example may look like:

Because the classes in the $map each implement the ServiceProviderInterface from this package, the ServiceProviderInvoker included knows how to attach them to the Container.

Conclusion

At this point, the container.php file is completely eliminated in favor of smaller, separated providers capable of being individually read in by the autoloader. There is a testable ServiceLoader which can be configured with the right strategy for loading in services and providers, itself being passed or instantiated wherever it makes the most sense for the consuming application.

To Do

Notes and Issues

Please note that this is a new package, currently in beta. Feel free to reach out with ideas, bug reports, or contribution questions.

Additional Documentation

You may run the API Doc build target to produce and peruse API documentation for this package.

Running the Build/Test Suite

This package makes extensive use of the Phing build tool.

Below is a list of notable build targets, but please feel free to peruse the build.xml file for more insight.

Default Target

./vendor/bin/phing will execute the build target (the same as executing ./vendor/bin/phing build). This performs a linting, syntax check, runs all static analysis tools, the test suite, and produces API documentation.

"Full" Packaging Target

Executing ./vendor/bin/phing package will run all above checks and, if passing, package the source into a shippable file with only the relevant source included therein.

Selected Individual Targets

License Latest Stable Version Latest Unstable Version Total Downloads


All versions of service-provisioning with dependencies

PHP Build Version
Package Version
Requires php Version >=7.0
psr/container Version ^1.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package improvframework/service-provisioning contains the following files

Loading the files please wait ....