使用laravel的依赖注入系统与CRUD模型等多实例对象的正确/最佳方式是什么?
PHP-land的某些角落目前的时尚说下面的代码是"坏"
function someMethod()
{
/* .. stuff ... */
$object = new \App\SomeModel;
$object->some_prop = 'some value';
$object->save();
/* .. other stuff ... */
}
这很糟糕,因为此方法现在依赖于新的对象实例化。目前的时尚说,对象应该通过某种依赖注入系统注入,比如Laravel的automatic constructor dependency injection。
然而 - 注入雄辩的模型似乎有问题
/*...*
public function __construct(\App\SomeModel $object)
{
$this->someModel = $object;
}
function someMethod()
{
/* .. stuff ... */
$object = $this->someModel;
$object->some_prop = 'some value';
$object->save();
/* .. other stuff ... */
}
/*...*/
目前尚不清楚Laravel的自动构造函数依赖注入是否每次都创建新实例,或者注入的对象是否是单实例对象。它也没有处理你想要使用Eloquent的静态助手的情况
function someMethod($object_id)
{
//another dependency
\App\SomeModel::find($object_id);
//but this doesn't work
$this->someModel->find($object_id);
}
在Laravel应用程序中是否有一种普遍接受的方法来处理这个问题?有人说你应该注入工厂。其他人说存储库。我想知道Laravel开发人员和的一般做法是什么,如果Laravel附带任何可以帮助的东西(基础工厂/存储库实现等)
答案 0 :(得分:1)
感谢LaraChat Slack的一些帮助,我自己想出了这个。
事实证明,除了自动构造函数依赖注入之外,Laravel还有一种特殊形式的依赖注入,可以与 a router's callback methods/functions的任何一起使用。
考虑此代码示例
Route::get('api/users/{user?}', function (App\User $user) {
return $user->email;
});
如果使用变量({user}
)设置路径字符串,Laravel将扫描您的路由处理程序(上面是一个匿名函数,但它也适用于控制器方法)参数类型提示其短类名称与变量名称(上面的App\User
)匹配。如果找到,则Laravel将实例化加载的 Eloquent对象,而不是从URL传入参数。如果省略了可选参数,您将获得指定类型的空白对象。
答案 1 :(得分:1)
Laravel DI的广泛讨论很棒。涵盖了类和接口的使用以及更多内容。我找到的最佳参考。 https://gist.github.com/davejamesmiller/bd857d9b0ac895df7604dd2e63b23afe
Laravel具有强大的控制反转(IoC)/依赖注入(DI)容器。不幸的是,官方文档并未涵盖所有可用功能,因此我决定尝试对其进行测试并自己记录。以下基于Laravel 5.4.26-其他版本可能会有所不同。
答案 2 :(得分:0)
我有一点玩这个(没有严肃的测试),看起来它是可能的 - 事实上,我更喜欢它这样做,并在未来看它。样品(未经测试)如下:
use App/Models/Foo;
class FooController {
private $model;
public function __construct(Foo $model)
{
$this->model = $model;
}
public function show(Request $request, $id)
{
$foo = $this->model->where($this->model->getKeyName(), '=', $id)->first();
dd($foo);
}
public function store(Request $request)
{
$foo = $this->model->newInstance();
$foo->bar = $request->get('baz');
$foo->save();
}
}
在雄辩的立面上找到帮助者,比如查找,很不错,但基本上它们是标准的(...) - > get() - > first()。