Laravel IoC 和单例模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17351658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:02:21  来源:igfitidea点击:

Laravel IoC and singleton pattern

laravellaravel-4

提问by David Marko

I'm trying to use Laravel IoC by creating a singleton object. I'm following the pattern from tutorial as below. I have put a Log message into object (Foobar in this example) constructor and I can see that object is being created every time I refresh page in browser. How is the singleton pattern meant for Laravels IoC? I understood that its shared object for entire application but its obviously being created every time its requested by App:make(...) Can someone explain please. I thought I would use the singleton pattern for maintaining shared MongoDB connection.

我试图通过创建一个单例对象来使用 Laravel IoC。我正在遵循教程中的模式,如下所示。我已将 Log 消息放入对象(本例中为 Foobar)构造函数中,并且每次在浏览器中刷新页面时,我都可以看到正在创建该对象。Laravel IoC 的单例模式是什么意思?我知道它是整个应用程序的共享对象,但显然每次 App:make(...) 请求时都会创建它,有人可以解释一下吗。我想我会使用单例模式来维护共享的 MongoDB 连接。

App::singleton('foo', function()
{
    return new FooBar;
});

回答by The Alpha

What has been said in Laravel Doc

中所说的 Laravel Doc

Sometimes, you may wish to bind something into the container that should only be resolved once, and the same instance should be returned on subsequent calls into the container:

有时,您可能希望将一些只应解析一次的内容绑定到容器中,并且在后续调用容器时应返回相同的实例:

This is how you can bind a singletonobject and you did it right

这就是你如何绑定一个singleton对象并且你做对了

App::singleton('foo', function()
{
    return new FooBar;
});

But, the problem is, you are thinking the whole process of the requestand responsein a wrong way. You mentioned that,

但是,问题是,你所想的全过程request,并response以错误的方式。你提到过,

I can see that object is being created every time I refresh page in browser.

每次在浏览器中刷新页面时,我都可以看到正在创建该对象。

Well, this is normal behavior of HTTPrequest because every time you are refreshing the page means every time you are sending a new request and every time the application is booting up and processing the request you've sent and finally, once the application sends the response in your browser, it's job is finished, nothing is kept (session, cookie are persistent and different in this case) in the server.

嗯,这是HTTP请求的正常行为,因为每次刷新页面意味着每次发送新请求以及每次应用程序启动并处理您发送的请求时,最后,一旦应用程序发送响应在您的浏览器中,它的工作已完成,服务器中没有任何内容(会话、cookie 在这种情况下是持久的且不同)。

Now, it has been said that the same instance should be returned on subsequent calls, in this case, the subsequent calls mean that, if you call App::make(...)several times on the same request, in the single life cycle of the application then it won't make new instances every time. For example, if you call twice, something like this

现在,据说the same instance should be returned on subsequent calls,在这种情况下,后续调用意味着,如果您App::make(...)对同一个请求多次调用,则在应用程序的单个生命周期中,它不会每次都创建新实例。例如,如果你调用两次,像这样

App::before(function($request)
{
    App::singleton('myApp', function(){ ... });
});

In the same request, in your controller, you call at first

在同一个请求中,在您的控制器中,您首先调用

class HomeController {
    public function showWelcome()
    {
        App::make('myApp'); // new instance will be returned
        // ...
    }
}

And again you call it in afterfilter second time

然后你再次在after过滤器中调用它

App::after(function($request, $response)
{
    App::make('myApp'); // Application will check for an instance and if found, it'll  be returned
});

In this case, both call happened in the same request and because of being a singleton, the container make only one instance at the first call and keeps the instance for the after use and returns the same instance on every subsequent calls.

在这种情况下,两个调用都发生在同一个请求中,并且由于是单例,容器在第一次调用时只创建一个实例,并保留实例以备后用,并在每次后续调用中返回相同的实例。

回答by Half Crazed

It is meant to be used multiple times throughout the applications instance. Each time you refresh the page, it's a new instance of the application.

它旨在在整个应用程序实例中多次使用。每次刷新页面时,它都是应用程序的一个新实例。

Check this out for more info and practical usage: http://codehappy.daylerees.com/ioc-container

查看更多信息和实际用法:http: //codehappy.daylerees.com/ioc-container

It's written for L3, but the same applies for L4.

它是为 L3 编写的,但同样适用于 L4。