As Organizer 作为管理工具

One of the keys to building a well architected Laravel application is learning to use service providers as an organizational tool. When you are registering many classes with the IoC container, all of those bindings can start to clutter your app/start files. Instead of doing container registerations in those files, create service providers that register related services.

想制作一个结构优美的 Laravel 应用的话,就要去学习如何用服务提供者来管理代码。当你在注册 IoC 绑定的时候,所有代码都杂乱的塞进了app/start 路径下的文件里。 别再这样做了,使用服务提供者来注册这些吧。

Get It Started 万物之初

Your application's "start" files are all stored in the app/start directory. These are "bootstrap" files that are loaded based on the type of the request entering your application. Start files named after an environment are loaded after the global start.php file. Finally, the artisan.php start file is loaded when any console command is executed.

你应用的“启动”文件都储存在 app/start 目录下。根据不同的请求入口,系统会载入不同的启动文件。在全局的 start.php 文件加载后,系统会根据执行环境的不同来加载不同的启动文件。 此外,在执行命令行程序时,artisan.php 文件会被载入。

Let's explore an example. Perhaps our application is using Pusher to push messages to clients via WebSockets. In order to decouple ourselves from Pusher, it will be benificial to create an EventPusherInterface, and a PusherEventPusher implementation. This will allow us to easily change WebSocket providers down the road as requirements change or our application grows.

咱们来考虑这个例子。也许我们的应用正在使用 Pusher 来为客户推送消息。为了将我们的应用和 Pusher 解耦,我们要定义 EventPusherInterface 接口和对应的实现类 PusherEventPusher 。这样在需求变化或应用改进时,我们就可以随时轻松的改变推送服务提供商。

interface EventPusherInterface{
    public function push($message, array $data = array());
}

class PusherEventPusher implements EventPusherInterface{
    public function __construct(PusherSdk $pusher)
    {
        $this->pusher = $pusher;
    }
    public function push($message, array $data = array())
    {
        // Push message via the Pusher SDK...
    }
}

Next, let's create an EventPusherServiceProvider:

接下来我们创建一个 EventPusherServiceProvider:

use Illuminate\Support\ServiceProvider;

class EventPusherServiceProvider extends ServiceProvider {
    public function register()
    {
        $this->app->singleton('PusherSdk', function()
        {
            return new PusherSdk('app-key', 'secret-key');
        }

        $this->app->singleton('EventPusherInterface', 'PusherEventPusher');
    }
}

Great! Now we have a clean abstraction over event pushing, as well as a convenient place to register this, and other related bindings, in the container. Finally, we just need to add the EventPusherServiceProvider to our providers array in the app/config/app.php configuration file. Now we are ready to inject the EventPusherInterface into any controller or class within our application.

很好! 我们对事件推送进行了清晰的抽象,同时我们也有了一个很不错的地方进行注册、绑定其他相关的东西到容器里。最后一步只需要将 EventPusherServiceProvider 写入 app/config/app.php 文件内的 providers 数组里就可以了。现在这个应用里的 EventPusherInterface 已经被绑定到了正确的实现类上。

Should You Singleton? 要使用单例么?

You will need to evaluate whether to bind classes with bind or singleton. If you only want one instance of the class to be created per request cycle, use singleton. Otherwise, use bind.

用不用单例可以这样来考虑:如果在一次请求周期中该类只需要有一个实例,就使用singleton;否则就使用bind。

Note that a service provider has an $app instance available via the base ServiceProvider class. This is a full Illuminate\Foundation\Application instance, which inherits from the Container class, so we can call all of the IoC container methods we are used to. If you preffer to use the App facade inside the service provider, you may do that as well:

    App::singleton('EventPusherInterface', 'PusherEventPusher');

Of course, service providers are not limited to registering certain kinds of services. We could use them to register our cloud file storage services, database access services, a custom view engine such as Twig, etc. They are simply bootstrapping and organizational tools for your application. Nothing more.

当然服务提供者的功能不仅仅局限于消息推送。像是云存储、数据库访问、自定义的视图引擎比如 Twig 等等都可以用这种模式来设置。服务提供者就是你的应用里的启动代码和管理工具,没什么神奇的。

So, don't be scared to create your own service providers. They are not something that should be strictly limited to distributed packages, but rather are great organizational tools for your own applications. Be creative and use them to bootstrap your various application components.

所以大胆的去创建你自己的服务提供者。并不是你非要发布个什么软件包才需要服务提供者,他们只是非常好的管理代码的工具。使用它们的力量去管理好应用中的各个组件吧。

results matching ""

    No results matching ""