laravel - Laravel IoC Container - 绑定一个单例,然后在没有原始参数时返回它
问题描述
我们正在尝试注册一个单身人士,例如
$this->app->singleton('blah', function ($app, $options) {
return $app->makeWith(Something::class, $options);
});
在我们的构造Something::class
中logger('started')
然后我们通过控制器中的容器创建类,例如
$something = app()->makeWith('blah', ['x' => 'y'])
我们检查日志,您可以看到started
然后在其他地方我们尝试将其拉出容器,例如
$instance = resolve('blah');
但是日志显示另一个started
这表明容器没有返回与构造执行两次相同的实例。
这可能是因为当我们调用时,resolve
我们没有传递与实例化相同的选项。
如果是这样,我们如何在不设置静态变量的情况下解决这个问题?
解决方案
您无法同时创建单例和使用参数。以下是来自的相关代码Container.php
:
// If an instance of the type is currently being managed as a singleton we'll
// just return an existing instance instead of instantiating new instances
// so the developer can keep using the same objects instance every time.
if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
return $this->instances[$abstract];
}
接着
// If the requested type is registered as a singleton we'll want to cache off
// the instances in "memory" so we can return it later without creating an
// entirely new instance of an object on each subsequent request for it.
if ($this->isShared($abstract) && ! $needsContextualBuild) {
$this->instances[$abstract] = $object;
}
请注意,$needsContextualBuild
如果实例是使用 makeWith 和参数创建的(除了具有上下文绑定时),则为 true。
如果您希望无参数resolve
始终解析最后解析的实例,您可以执行以下操作:
//Bind or singleton doesn't matter now
$this->app->bind('blah', function ($app, $options) {
return $app->makeWith(Something::class, $options);
});
$this->app->afterResolving('blah', function ($resolvedObject) {
$this->app->instance('blah', $resolvedObject);
});
$this->app->makeWith('blah', [ 'a' => 'b' ]); //New object 1
$this->app->make('blah'); //Reused object 1
$this->app->makeWith('blah', [ 'a' => 'b' ]); //New object 2
$this->app->make('blah'); //Reused object 2
请注意,使用不同的上下文解析相同的别名仍将解析一个新对象并将该对象绑定为'blah'
.
推荐阅读
- github - 如何为相应的提交启用和使用“提交更改”部分中自动填充的灰色提交消息?
- android - 在 FirestoreRecyclerAdapter 中膨胀多个布局
- multithreading - 纹理名称在OpenGL中是唯一的吗?
- java - Java变量初始化不同的处理方式?
- c++ - 无法从文件中查找和打印具有特定前缀的数据
- laravel - 如何将 vuex 计算属性传递给 vuejs 图表数据?
- docker - Docker坚持课程教程
- android - 如何在 Android 中测试应用内更新?
- c - 分配结构数组时遇到问题
- android-viewmodel - Koin:如何在 WorkManager 中注入 sharedViewModel?