edit

Using Service Providers

Introduction

Service Providers developed to extend the Framework's core without hacking it.

In this overview you will learn how to write your own service providers and register them with your Skytells application.

Remember

This tutorial assumes you’ve downloaded Skytells Framework and installed the framework in your development environment.

However, we've mentioned before that Service Providers are Optional
So If you prefer to extend your app's functionality with the main Framework's core, You may use the Service Providers as documented on this page.


Look Back

We're strongly recommends to read Service Providers Concepts
For more information about this tutorial before reading the contents of this page.


Service Providers Configuration

Of course all service providers must be added to the main Settings.php file to inform the Framework to register each service provider on its core before loading the controllers.

If you open the Application/Misc/Settings.php file included with Skytells,
You will see a providers array looks like this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?
/*
|-------------------------------------------------------------------------------
| SERVICE PROVIDERS
|-------------------------------------------------------------------------------
|
| Service providers are the central place of all Skytells application bootstrapping.
| Your own application, as well as all of Skytells Framework's core services are
| bootstrapped via service providers.
*/
 $Settings['USE_PROVIDERS'] = FALSE;
 $SF_PROVIDERS = [
  /*
   * Application Service Providers...
   */
  "AppServiceProvider" => App\Providers\AppServiceProvider::class
  ];

Configuration Definition :

Option Type Details
$Settings['USE_PROVIDERS'] Array Key This option enables or disables bootstrapping service providers at the startup point of your app.
$SF_PROVIDERS Array This array contains all developed service providers by you, All service providers must have the right key & value types, for example : "Name" => ClassName::class

Creating a Service Provider

Now lets create our first Service Provider!

Remember

Before Creating a Service Provider, Please make sure to understand the Service Providers Architecture.

Now you have two options to create your service provider

Create Service Provider via CLI

The Skytells CLI can generate a new provider via the create provider command:

Do not use sudo

Please do not perform the CLI commands with $ > sudo
because it effects the permissions for the generated files.

1
$ > php skytells create provider MyServiceProvider

Of course you need to change MyServiceProvider with the name of your provider. Once the command is performed, All files required for your service provider will be created.


Writing Service Provider

In order for you to create a Service provider manually,
You need first to create the dependencies for your service.

Here are the procedures for creating a Service Provider.

  1. Creating Service Contract
  2. Creating Provider Service
  3. Creating Provider Bootstrap File

Are you ready?
Lets get started by creating our contract file..

Service Contract

First of all, We need to create a contract for our Service provider.

Navigate to the Contracts Dir :

1
Application/Misc/Providers/Contracts

Create a new PHP file with given name of HelloContract.php and put the following code on it.

1
2
3
4
5
6
<?php
Namespace Hello\Contracts; // <-- Your namespace is optional
Interface HelloContract
{
  public function sayHello();
}

Remember

Namespaces are optional, but we recommend to use namespaces on your service providers.

Okay, Now the Service contract has been created in Application/Misc/Providers/Contracts

Lets move on and create our Provider Service

Provider Service

The Provider Service is the heart of the Service Provider, In other words, Its your own core which extended from the Framework's core.

Now navigate to the Services Dir :

1
Application/Misc/Providers/Services

Create a new PHP file with given name of Hello.php and put the following code on it.

Remember

This file is the heart of everything inside your service provider, So all functions must be written on it, and declared on HelloContract.php File.

1
2
3
4
5
6
7
8
<?php
use Hello\Contracts; // <-- We need to use the contract namespace.
Class Hello implements HelloContract {
    public function sayHello()
    {
        return 'Hello World!';
    }
}

Now we've created our provider service file which contains only one function as implemented from the HelloContract.php File.

Now lets move on to the final step to create the Provider Bootstrap file.

Provider Bootstrap File

The Provider Bootstrap File is the file who is responsible for booting up your service provider at the Framework's startup.

Please Focus

Please pay attention to this step, because its the most important thing for your app provider to run.

Now, Lets get back to the Providers directory.

1
Application/Misc/Providers

Create a new PHP file in name of HelloServiceProvider.php
And Put the following code on it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
Namespace Hello\Providers;
// ^-- This is a new namespace associated for the bootstrapping file itself.

use Skytells\Support\ServiceProvider;
use Skytells\Foundation;
Class HelloServiceProvider extends ServiceProvider {

  protected $defer = false;

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
      // Of course we need to load the provider's dependencies when booting the provider.
      // This method will be called automatically when bootstrapping this file.
      return [
        'contracts' => ['AppContract'],
        'services'  => ['AppService']
      ];
    }
    /**
     * Register any application services.
     *
     * @return void
     * @param Foundation::$App is a foundation var which contains the boot container data.
     * for the entire framework dependencies.
     */
    public function register()
    {
      // Now We need to register the Service file which saved in :
      // Application/Misc/Providers/Services

      Foundation::$App->singleton(Hello::class, function ($app) {
            return new Hello();
        });
    }
    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
       // Start providing service
        return [Hello::class];
    }
}

Now lets Explain what we have written in this file.

First of all, We've informed the main core of the framework that the provider contains services and interfaces which must be loaded upon starting up the service provider by setting this to false.

1
2
<?
protected $defer = false;

2rd Step, We've added a new namespace for the Service provider bootstrap file.

1
2
3
<?
Namespace Hello\Providers;
// ^-- This is a new namespace associated for the bootstrapping file itself.

3rd Step, We've created the boot function which is REQUIRED for bootstrapping the service provider's dependencies.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?
public function boot()
{
  // Of course we need to load the provider's dependencies when booting the provider.
  // This method will be called automatically when bootstrapping this file.
  return [
    'contracts' => ['AppContract'],
    'services'  => ['AppService']
  ];
}

Now lets explain the above code,

Name Type Details
contracts Array This array must contains all contracts associated with this service provider, this array is required to run your provider.
services Array This array must contains all services associated with this provider, this array is required to run your provider.

4rd Step, We've created the register function which is REQUIRED also for bootstrapping the service provider's dependencies.

1
2
3
4
5
6
7
<?
public function boot()
{
  Foundation::$App->singleton(Hello::class, function ($app) {
        return new Hello();
    });
}

Now lets explain the above code, This function is called upon detecting your service provider by Skytells's Core.

The Foundation::$App->singleton() binding the your service to the Controller which used for serving the Provider.

5th Step, We've created the provides function which is REQUIRED to start seeding your service across the global core.

1
2
3
4
5
<?
public function provides()
{
  return [Hello::class];
}

This function returns your service as a Class to be injectable to Controllers or Models ..etc.

Adding Provider to Settings File

Now, After we've created our provider, Lets Add it into our Providers List mentioned in the top of this page.

Open the Application/Misc/Settings.php file included with Skytells,

And Add your provider to the Providers array

1
"HelloServiceProvider" => Hello\Providers\HelloServiceProvider::class

Now The providers array looks like this.

1
2
3
4
5
6
7
8
9
<?
 $Settings['USE_PROVIDERS'] = TRUE; // <--- Must be true
 $SF_PROVIDERS = [
  /*
   * Application Service Providers...
   */
  "AppServiceProvider" => App\Providers\AppServiceProvider::class,
  "HelloServiceProvider" => Hello\Providers\HelloServiceProvider::class // <-- Added to the array.
  ];

Congrats!

Now, Congrats, Your Service Provider has been created and added.

Using Service Providers

Now, In order for you to use this Service Provider, Open up your Controller from :

1
Application/Resources/Controllers

And create a new stdObject for your Provider or simply call the provider by performing this :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
 use Skytells\UI\View;
 use Skytells\Runtime;
 use Hello\Contracts;
 use Hello\Providers\Hello;
 Class Home extends \Controller implements \IController {

   public function __construct(Hello $HelloService, $Ref = 'Core', $IsAlias = false) {
     echo $HelloService->sayHello();
     // Outputs : (string) Hello World.
   }
 }

Now you should see Hello World printed on screen upon accessing the controller.
This function sayHello() called from The Service File we created before.