Prior to me discovering how the Laravel internals work, I would define static methods for most of my services. It quickly gets difficult to manage, once you need to keep non static state for a service, or you want dynamic behavior that is determined at runtime. In this post I’ll share how I defined my own
Asset class facade that is registered to the Laravel container in a service provider. First, let’s take a minute to understand my original
Asset class. It was your typical static class.
At the end of this post, we’ll turn the following code into a fluent interface.
$assetManger = new AssetManager( app_path(), false, 'https://cdn.amezmo.net' ); $assetManger->js(); // After our service provider / facade combo Asset::js();
The problem with the static asset class however, is that you cannot use Laravel’s DI container to inject services, such as a configuration block, or anything else that you would need. So, for the new non static implementation. I started off by following Laravel’s pattern of putting each provider in it’s own directory. Create a new directory under your
app directory called
Asset. I added
AssetManagerInterface to best follow the SOLID principles. However, it isn’t necessary to always implement an interface for a simple service .
Implementing the Service Provider
The Laravel DI container is powerful. It’s especially useful for registering singelton classes, such as the
Asset class or a connection Redis, for example. Lot’s of Laravel’s built-in providers are singeltons.
It’s worth noting that you do not have to register your services directly. Laravel is smart enough to construct an instance of your service. However, since I am passing in a non-reference type as the first argument, Laravel would not be able to, simply because primitive values have no context. Once we have the service provider register to the container, we’re ready to add it to our
app/config/app.php configuration array
The entry added to the
aliases array is that the facade
Asset can be invoked from a view. Now let’s take a look at
AssetManager where the real logic, hiding behind the facade actually takes place I’ve added other methods in this class. Perhaps it might give you some inspiration in your own projects.
As you can see, the constructor defines it’s dependencies and we provide them in the
AssetServiceProvider This is great for performance, because we will be able to store the configuration in memory, and not, for example, call
env() many times, which may end up calling into
getenv from the C standard library.
Asset facade is very simple. It defines one method called
getFacadeAccessor with returns a string with the value we’ve returned from
Benefits of Service Provider pattern with Facades
- Being able to mock your service properly
- Not depending on any hard coded dependencies.
- All your dependencies are defined in your constructor, so you can swap in specific implementations for your use specific use case. For example, if you need different behavior for the service in a production or development environment.
This blog is hosted by Amezmo. Amezmo makes zero-downtime deployment for PHP easy.