---
title: Service Providers
---

# Service Providers

<div class="documentation__toc"></div>

## Introduction

Service providers are the central class of all addon registering. Service providers let you define views, overrides, routes, commands, schedules, and more.

This documentation assumes you already have an understanding of [Laravel service providers](https://laravel.com/docs/providers).

> [For creating addon service providers see the addon development section.](../addon-development/core-principles/service-providers){.link}

### Defining Service Providers

Service providers are usually created for you when using `make:addon`. Even your `theme`, which every project will likely have, is generated with a service provider.

If you would like to make your own you can do so by creating a class that extends `Anomaly\Streams\Platform\Addon\AddonServiceProvider`.

If your addon is `ExampleModule` your service provider should be called `ExampleModuleServiceProvider` to be detected automatically.

> Service providers for installable addons will be ignored unless they are both `installed` and `enabled`.{.note}

```php
<?php namespace Anomaly\ExampleModule;

use Anomaly\Streams\Platform\Addon\AddonServiceProvider;
use Illuminate\Routing\Router;

class ExampleModuleServiceProvider extends AddonServiceProvider
{

    /**
     * Additional addon plugins.
     *
     * @type array|null
     */
    protected $plugins = [];

    /**
     * The addon Artisan commands.
     *
     * @type array|null
     */
    protected $commands = [];

    /**
     * The addon's scheduled commands.
     *
     * @type array|null
     */
    protected $schedules = [];

    /**
     * The addon API routes.
     *
     * @type array|null
     */
    protected $api = [];

    /**
     * The addon routes.
     *
     * @type array|null
     */
    protected $routes = [];

    /**
     * The addon middleware.
     *
     * @type array|null
     */
    protected $middleware = [
        //Anomaly\ExampleModule\Http\Middleware\ExampleMiddleware::class
    ];

    /**
     * Addon group middleware.
     *
     * @var array
     */
    protected $groupMiddleware = [
        //'web' => [
        //    Anomaly\ExampleModule\Http\Middleware\ExampleMiddleware::class,
        //],
    ];

    /**
     * Addon route middleware.
     *
     * @type array|null
     */
    protected $routeMiddleware = [];

    /**
     * The addon event listeners.
     *
     * @type array|null
     */
    protected $listeners = [
        //Anomaly\ExampleModule\Event\ExampleEvent::class => [
        //    Anomaly\ExampleModule\Listener\ExampleListener::class,
        //],
    ];

    /**
     * The addon alias bindings.
     *
     * @type array|null
     */
    protected $aliases = [
        //'Example' => Anomaly\ExampleModule\Example::class
    ];

    /**
     * The addon class bindings.
     *
     * @type array|null
     */
    protected $bindings = [];

    /**
     * The addon singleton bindings.
     *
     * @type array|null
     */
    protected $singletons = [];

    /**
     * Additional service providers.
     *
     * @type array|null
     */
    protected $providers = [
        //\ExamplePackage\Provider\ExampleProvider::class
    ];

    /**
     * The addon view overrides.
     *
     * @type array|null
     */
    protected $overrides = [
        //'streams::errors/404' => 'module::errors/404',
        //'streams::errors/500' => 'module::errors/500',
    ];

    /**
     * The addon mobile-only view overrides.
     *
     * @type array|null
     */
    protected $mobile = [
        //'streams::errors/404' => 'module::mobile/errors/404',
        //'streams::errors/500' => 'module::mobile/errors/500',
    ];

    /**
     * Register the addon.
     */
    public function register()
    {
        // Run extra pre-boot registration logic here.
        // Use method injection or commands to bring in services.
    }

    /**
     * Boot the addon.
     */
    public function boot()
    {
        // Run extra post-boot registration logic here.
        // Use method injection or commands to bring in services.
    }

    /**
     * Map additional addon routes.
     *
     * @param Router $router
     */
    public function map(Router $router)
    {
        // Register dynamic routes here for example.
        // Use method injection or commands to bring in services.
    }

}
```

## Definitions

### Plugins

Use the `$plugins` property to define plugins. This is helpful when developing a module that requires it's own plugin.

```php
protected $plugins = [
    \Anomaly\UsersModule\UsersModulePlugin::class,
];
```

### Artisan Commands

Use the `$commands` property to define [Artisan commands](../core-concepts/cli-commands) provided by the addon.

```php
protected $commands = [
    \Anomaly\ExampleModule\Console\DoWork::class,
];
```

### Scheduled Tasks

Use the `$schedules` property to define [scheduled tasks](../core-concepts/scheduled-tasks).

```php
protected $schedules = [
    'daily' => [
        \Anomaly\LogsModule\Console\ArchiveLogs::class,
    ],
    'dailyAt|11:00' => [ // dailyAt('13:00')
      \Anomaly\LogsModule\Console\ArchiveLogs::class,
    ],
    'twiceDaily|1, 13' => [ // twiceDaily(1, 13)
      \Anomaly\LogsModule\Console\ArchiveLogs::class,
    ],
    '*/10 * * * *' => [
        \Anomaly\LogsModule\Console\ScrapeLogs::class,
    ],
];
```

### Routes

Use the `routes` property to define addon routes. Routes defined here are very similar to the arguments you would typically pass [Laravel's router](https://laravel.com/docs/routing):

```php
protected $routes = [
    'login' => 'Anomaly\UsersModule\Http\Controller\LoginController@login',
];
```

> [Learn more about route definitions.](#the-basics/routing){.link}

### Middleware

Use the `$middleware` property to define middleware to push into the `MiddlewareCollection`. Middleware in this collection are ran for every request:

```php
protected $middleware = [
    \Anomaly\UsersModule\Http\Middleware\CheckSecurity::class,
];
```

> [Learn more about middleware.](#the-basics/middleware){.link}

### Event Listeners

use the `$listeners` property to define event listeners.

```php
protected $listeners = [

	// ...
	
    'Anomaly\UsersModule\User\Event\UserWasLoggedIn' => [
        'Anomaly\UsersModule\User\Listener\TouchLastLogin',
    ],
];
```

You can also dictate the listener's `priority` by specifying as `listener => priority`. Listeners are ran in order of highest to lowest priority.

```php
protected $listeners = [

	// ...
	
    'Anomaly\Streams\Platform\Application\Event\ApplicationHasLoaded' => [
        'Anomaly\UsersModule\User\Listener\TouchLastActivity' => -100,
    ],
];
```

### Aliases

Use the `$aliases` property to define aliases with the service container.

```php
protected $aliases = [
    'users' => \Anomaly\UsersModule\User\Contract\UserRepositoryInterface::class,
];
```

### Bindings

Use the `$bindings` property to define bindings with the service container.

```php
protected $bindings = [
    'login' => 'Anomaly\UsersModule\User\Login\LoginFormBuilder',
];
```

### Singletons

Use the `$singletons` property to define singleton bindings with the service container..

```php
protected $singletons = [
    'Anomaly\UsersModule\User\Contract\UserRepositoryInterface' => 'Anomaly\UsersModule\User\UserRepository',
];
```

### Service Providers

Sometimes you might ship your addon with a package dependency that requires a service provider. Use the `$providers` property to register other service providers.

```php
protected $providers = [
    \TeamTNT\Scout\TNTSearchScoutServiceProvider::class,
];
```

### View Overrides

Use the `$overrides` property to specify `view => override` definitions to use _should the addon be relative to the current request_.

```php
protected $overrides = [
    'streams::form/partials/wrapper' => 'example.theme.test::overrides/field_wrapper',
];
```

### Mobile View Overrides

Use the `$overrides` property to specify mobile-only `view => override` definitions to use _should the addon be relative to the current request_.

```php
protected $mobile = [
    'streams::form/partials/wrapper' => 'example.theme.test::mobile/field_wrapper',
];
```

## Request Lifecycle

### Register

The `register` method is ran very early in addon registration. You should only bind things into the [service container](../core-concepts/service-container). Typically, you should never attempt to use any class or functionality from another addon within the `register` method. Otherwise, you may accidentally use something that is provided but has not been registered yet itself.

Register is ran after the above definitions have been registered so you may use those at will.

```php
<?php

namespace Anomaly\ExampleModule;

use Riak\Connection;
use Anomaly\Streams\Platform\Addon\AddonServiceProvider;

class ExampleModuleServiceProvider extends AddonServiceProvider
{

    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Connection::class, function ($app) {
            return new Connection(config('riak'));
        });
    }
}
```

### Boot

The `boot` method is called after all other addon service providers have been registered. It is now safe to use functionality from other addons.

```php
<?php

namespace Anomaly\ExampleModule;

use Anomaly\Streams\Platform\Addon\AddonServiceProvider;

class ExampleModuleServiceProvider extends AddonServiceProvider
{

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        if (auth()->user()) {
        	// Register a little something extra special.
        }
    }
}
```

### Map

The `map` method is called last and gives you an opportunity to do some routing based on logic from another addon perhaps.

```php
<?php

namespace Anomaly\ExampleModule;

use Illuminate\Routing\Router;
use Anomaly\Streams\Platform\Addon\AddonServiceProvider;

class ExampleModuleServiceProvider extends AddonServiceProvider
{

    /**
     * Map any additional services.
     *
     * @return void
     */
    public function map(Router $router)
    {
        $router->($path, $route);
    }
}
```
