walkor / webman-framework

webman-framework
116 stars 57 forks source link

Container的make方法加个参数,是否保留最后一次实列 #60

Closed ichynul closed 2 years ago

ichynul commented 2 years ago

在控制器不复用的时候,控制器是通过Container的make方法,未保留实列,如果其他地方想要调用Container的get拿不到,而是新实列化的。 Container的make方法加个参数,对于某些特殊对象,可以自行决定是否保留最后一次实列。 public function make(string $name, array $constructor = [], bool $saveInstance = false)

if ($request->controller) {
        if (Container::has($request->controller)) {
            $instance = Container::get($request->controller);
        }
}
walkor commented 2 years ago

make方法预期就是不保存实例的,如果make方法保存实例析构函数就不会执行,与预期不符。 get方法也不应该获取make方法的实例,感觉很混乱。

ichynul commented 2 years ago

make任然是每次都新建实列的,不判断是否存在。只是保留一些特殊的实列。 比如在确定本次请求已经make过的对象,后面可以通过get拿到。 比如想拿到当前控制器实列,make后不保留的话,没办法拿到。用get只会重新实列化一个,如果析构函数里面有一些操作,会重复执行。

walkor commented 2 years ago

什么需求需要获得控制器实例?

ichynul commented 2 years ago

就是以前参考ActionHook弄的中间件,不过现在改了一下,也倒不是一定有这个需求。 一样的ActionHook这个插件,如果用户开启了控制器复用,但没移除这个扩展,那是有问题的。 $controller = Container::get($request->controller);这句会新实列化控制器,也许仍然能达到用户想要的效果,但感觉有点怪异。

如果按我的方案来,起码后置中间件可以用一下。

ichynul commented 2 years ago

把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]);
            }
        }