在Hack中编写IoC容器

 soar 发布于 2023-01-15 18:34

我正在将PHP项目转换为Hack,我遇到了一些障碍.我想要做的是将一个IoC容器从PHP重写为Hack,并且我在通过Hack类型检查工具获取所有内容时遇到了一些麻烦.

基本上我所拥有的是一个容器,它允许您将字符串注册到闭包映射.想法是闭包包含实例化类的逻辑.容器还存储它创建的实例,还允许您强制创建新实例.这是我的容器代码:

 $instances = Map {};
    private Map $registered = Map {};

    public function register(string $alias, (function (Container): mixed) $closure): void
    {       
        $this->registered[$alias] = $closure;
    }

    public function get(string $alias): ?mixed
    {
        if (!$this->registered->contains($alias)) {
            return null;
        }

        $instance = $this->instances->get($alias);
        if ($instance !== null) {
            return $instance;
        }

        $closure = $this->registered->get($alias);
        if ($closure !== null) {
            $this->instances->set($alias, $closure($this));
        }
        return $this->instances->get($alias);
    }

    public function getNew(string $alias): ?mixed
    {
        if (!$this->registered->contains($alias)) {
            return null;
        }

        $closure = $this->registered->get($alias);
        return ($closure !== null) ? $closure($this) : null;
    }
}

这个类本身似乎传递了类型检查器,但是当使用Container::get()或者Container::getNew(),因为返回是类型时mixed,当我尝试对这些返回的对象执行方法时,它会抛出此错误:

您正在尝试访问成员x,但这不是对象,它是一个混合值

现在我知道这是有道理的,因为混合显然允许非对象,所以我必须确保将这些代码包装在一个is_object(),但是这样做似乎并没有抑制类型检查器中的错误.有没有更好的方法来确认某些东西是Hack中的对象,类型检查器会理解?

此外,这个IoC容器类在很大程度上依赖于混合类型,这对我来说有点难看.在运行时也必须确保其返回是对象并不理想.有没有更好的方法可以做到这一点?我确实尝试过将混合更改为接口(如IContainable或其他东西)的想法,并且我想在容器中存储任何类实现这个,但是类型检查器抱怨IContainable接口不包含该方法我试图调用从容器返回的对象(所以代码中的同一点出错,但原因不同).也许我接近这种方法的成功?

谢谢你的帮助.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有