Closed ichynul closed 2 years ago
make方法预期就是不保存实例的,如果make方法保存实例析构函数就不会执行,与预期不符。 get方法也不应该获取make方法的实例,感觉很混乱。
make任然是每次都新建实列的,不判断是否存在。只是保留一些特殊的实列。 比如在确定本次请求已经make过的对象,后面可以通过get拿到。 比如想拿到当前控制器实列,make后不保留的话,没办法拿到。用get只会重新实列化一个,如果析构函数里面有一些操作,会重复执行。
什么需求需要获得控制器实例?
就是以前参考ActionHook弄的中间件,不过现在改了一下,也倒不是一定有这个需求。
一样的ActionHook这个插件,如果用户开启了控制器复用,但没移除这个扩展,那是有问题的。
$controller = Container::get($request->controller);
这句会新实列化控制器,也许仍然能达到用户想要的效果,但感觉有点怪异。
如果按我的方案来,起码后置中间件可以用一下。
把make控制器放到call回调外面,再配合我这个方案,好像可以让前置/后置都可以拿到控制器实列吧
$controller_reuse = static::config($plugin, 'app.controller_reuse', true);
if (\is_array($call) && \is_string($call[0])) {
if (!$controller_reuse) {
try {
$call[0] = static::container($plugin)->make($call[0], [], true);
$call = function ($request, ...$args) use ($call, $plugin) {
return $call($request, ...$args);
};
} catch (Throwable $e) {
$call = function ($request, ...$args) use ($call, $plugin, $e) {
throw $e;
};
}
} else {
$call[0] = static::container($plugin)->get($call[0]);
}
}
在控制器不复用的时候,控制器是通过Container的make方法,未保留实列,如果其他地方想要调用Container的get拿不到,而是新实列化的。 Container的make方法加个参数,对于某些特殊对象,可以自行决定是否保留最后一次实列。
public function make(string $name, array $constructor = [], bool $saveInstance = false)