关于方法依赖注入的疑问?

file

代码如图,当我们调用created方法的时候,注入了一个Reply实力,那么当我们每次使用$reply->topic或者topic->user或者$reply->user的时候,是不是都存在一次查询情况?如果是的话怎么在注入的时候就能把关联的一次查询出来了,不然感觉每次都去查一遍很慢啊。还有就是app(TopicReplied::class)和new TopicReplied()是不是一样的?如果是new TopicReplied($reply)这种需要带参数的,用app()怎么写?

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
最佳答案

第一个问题:

因为依赖注入是框架在控制,目前我没有看到可以在这里注入时改变框架逻辑的方法,所以只有妥协,可以在进方法第一行就写

$reply->loadMissing(['topic', 'user', 'notify']);

这样就把三次查询合并成了一次查询了。

第二个问题:

这个问题涉及到ioc容器。

  • 如果一个类没有参数,没问题。 app(TopicReplied::class)
  • 如果一个类有参数,没问题。 app(TopicReplied::class) 。也是这样使用。

不过你会看到在绑定这个类的时候代码是这样的:

app()->bind(TopicReplied::class, function ($app) {
    return new TopicReplied($params);
});

ioc容器的作用就是在这里,它让你在实例化类的时候不用去关心要传什么参数。

所以,当没有参数的时候, app(TopicReplied::class)new TopicReplied() 是没有区别的。硬要说有区别,那就是用 app(TopicReplied::class) 时多执行了一些代码。:smile:

5年前 评论
讨论数量: 3

第一个问题:

因为依赖注入是框架在控制,目前我没有看到可以在这里注入时改变框架逻辑的方法,所以只有妥协,可以在进方法第一行就写

$reply->loadMissing(['topic', 'user', 'notify']);

这样就把三次查询合并成了一次查询了。

第二个问题:

这个问题涉及到ioc容器。

  • 如果一个类没有参数,没问题。 app(TopicReplied::class)
  • 如果一个类有参数,没问题。 app(TopicReplied::class) 。也是这样使用。

不过你会看到在绑定这个类的时候代码是这样的:

app()->bind(TopicReplied::class, function ($app) {
    return new TopicReplied($params);
});

ioc容器的作用就是在这里,它让你在实例化类的时候不用去关心要传什么参数。

所以,当没有参数的时候, app(TopicReplied::class)new TopicReplied() 是没有区别的。硬要说有区别,那就是用 app(TopicReplied::class) 时多执行了一些代码。:smile:

5年前 评论

@zedisdog 非常感谢,说得很详细。不过其中有些我还是模棱两可,让我自己边使用边体会吧。 :grin:

5年前 评论

问题一:注入了一个Reply实力,那么当我们每次使用$reply->topic或者topic->user或者$reply->user的时候,是不是都存在一次查询情况?

对这问题不是很明白。$reply->topic或者topic->user或者$reply->user 同
一个调用多次难到会存在多次 SQL 查询

问题二:如果是的话怎么在注入的时候就能把关联的一次查询出来了,不然感觉每次都去查一遍很慢啊。还有就是app(TopicReplied::class)和new TopicReplied()是不是一样的?

app() 这个助手函数,拿到的是服务容器实例。这个函数有两大作用,一
是绑定,二是解析。“app(TopicReplied::class)和new TopicReplied()是不
是一样的?” 这是两个完全不一样的动作也是完全不一样的结果。app(To
picReplied::class) 是解析已经绑定的服务, new TopicReplied() 是创建
对象,从动作上讲就好比一个是 GET 一个是 POST,从结果来对比全
等是false相等是true。 

问题三:如果是new TopicReplied($reply)这种需要带参数的,用app()怎么写?

这得重新绑定服务,重新绑定方式: app()->instance('自定义服务名称',
new TopicReplied($reply)), 注意: 如果重新绑定 Laravel 内置通知服
务,会不会造成其它问题,还得你自己去测试,还有你得自己去查看, 
TopicReplied 通知的服务名称

问题四:标题“关于方法依赖注入的疑问?”

依赖注入是利用 PHP 反射机制来完成的,通过反射得到构造函数依赖的
参数类型,然后从容器已有的绑定中,解析出对应参数类型服务实例,
传入构造函数完成实例化,这就是所谓依赖注入(DI)
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!