我有一个名为Surface的Eloquent模型,它依赖于ZipCodeRepository对象:
number[n].name = NULL;
和一个包含多个曲面的Address对象。
class Surface extends Model{
public function __construct(ZipCodeRepositoryInterface $zipCode){...}
我的问题是,当我致电class Address extends Model{
public surfaces() { return $this->hasMany('App/Surface'); }
}
时,我收到以下错误:
$address->surfaces
我认为IoC会自动注入。
答案 0 :(得分:20)
感谢@svmm引用the question mentioned in the comments。我发现你不能在模型上使用依赖注入,因为你必须改变构造函数上的签名,这不能与Eloquent框架一起使用。
在重构代码时,我作为中间步骤所做的是在构造函数中使用App::make
来创建对象,例如:
class Surface extends Model{
public function __construct()
{
$this->zipCode = App::make('App\Repositories\ZipCodeRepositoryInterface');
}
这样IoC仍然可以获取已实现的存储库。我只是这样做,直到我可以将函数拉入存储库以删除依赖项。
答案 1 :(得分:1)
但是,通过构造函数或方法注入将服务注入到您的模型中可能不是一个好习惯,请考虑以不需要这样做的方式设计系统,而是将模型注入到服务中.
让我们看一个例子(只是一个虚拟的例子,以便进入重点!)。
一种方法是:
class OrderController
{
function store(User $user, Order $order)
{
$basket = $user->getBasket();
$basket->addOrder($order);
}
}
class Basket
{
private $discountService;
public function __construct(DiscountService $discountService)
{
$this->discountService = $discountService;
}
function addOrder(Order $order)
{
$this->orders[] = $order;
$discount = $this->discountService->calculateFor($this->orders);
$this->discount = $discount;
}
}
class DiscountService
{
function calculateFor(array $orders) {
// code for calculating discount;
return $discount;
}
}
在这种方法中,我们将折扣服务注入到篮子模型中
另一种更好的方法是这样的:
class OrderController
{
private $discountService;
public function __construct(DiscountService $discountService)
{
$this->discountService = $discountService;
}
function store(User $user, Order $order)
{
$basket = $user->getBasket();
$basket->addOrder($order);
$this->discountService->setDiscount($basket);
}
}
class Basket
{
function addOrder(Order $order)
{
$this->orders[] = $order;
}
function getOrders()
{
return $this->orders;
}
function setDiscount(int $discount)
{
$this->discount = $discount;
}
}
class DiscountService
{
function setDiscount(Basket $basket) {
$discount = $this->calculateFor($basket->getOrders());
$basket->setDiscount($discount);
}
private function calculateFor(array $orders)
{
// code for calculating discount
return $discount;
}
}
答案 2 :(得分:0)
在Laravel 5.7中,您可以使用全局resolve(...)
方法。我不认为全局App
是在最新版本的Laravel中定义的。
$myService = resolve(ServiceName::class);