Öncelikle, umarım Bank sınıfınız bir model değildir.
Model değilse, normalde yapmanız gereken:
$this->app->bind(Bank::class, function($app) {
$account = optional(auth()->user())->bank_account;
return new Bank($account);
});
Service container binding işlemini Auth katmanının bulunmadığı ortamlarda da gerçekleştireceği için optional yardımcı yöntemi ile Trying to get property of non-object hatası alınmamasını sağladım. Burada şöyle bir sıkıntı olacak, $account değerinin içeriye null olarak girmesi söz konusu. Öyleyse içeride bunu kontrol etmeli ve yaptığınız gibi $account için getter/setter tanımlamanız gerekli. Ayrıca IoC prensibi sağlanması adına somut sınıf yerine arayüz enjekte etmeniz daha uygun olur.
Örneğin:
interface BankServiceInterface
{
public function setAccount(Account $account): BankService;
public function getAccount(): ?Account;
public function hasAccount(): bool;
public function getTransaction($startsAt, $endsAt);
protected function needsAccount();
}
class BankService implements BankServiceInterface
{
public $account;
public $hasAccount = false;
public function __construct(Account $account = null)
{
$this->account = $account;
$this->hasAccount = $account ? true : false;
}
public function setAccount(Account $account): BankService
{
$this->account = $account;
return $this;
}
public function getAccount(): ?Account
{
return $this->account;
}
public function hasAccount(): bool
{
return $this->account ? true : false;
}
public function getTransaction($startsAt, $endsAt)
{
$this->needsAccount();
//...
}
protected function needsAccount()
{
if(!$this->hasAccount()) {
throw new AccountNotProvidedException;
}
}
}
$this->app->bind(Bank::class, function($app) {
$account = optional(auth()->user())->bank_account;
return new Bank($account);
});
$this->app->bind(BankServiceInterface::class, Bank::class);
class TransactionController extends Controller
{
protected $bankService;
public function __construct(BankServiceInterface $bankService)
{
$this->bankService = $bankService;
}
public function index(Request $request): TransactionCollection
{
$startsAt = $request->input('starts_at');
$endsAt = $request->input('ends_at');
$transactions = $this->bankService->getTransactions($startsAt, $endsAt);
return new TransactionCollection($transactions);
}
}
Auth katmanının olmadığı durumlarda ise:
event(new TransactionRequested($user, $startsAt, $endsAt));
public function handle(TransactionRequested $event)
{
$transactions = $this->bankService
->setAccount($this->user->bank_account)
->getTransactions($this->startsAt, $this->endsAt);
//...
}
gibi.
Ekleme:
Inversion of Control, Dependency Injection, Interface Injection ve Service Container ile ilgili bir yazı hazırlıyordum. Yayınladığımda forumdan linkini paylaşırım ya da Medium ve LinkedIn hesabımdan görebilirsiniz:
https://medium.com/@mgsmus
https://www.linkedin.com/in/mustafa-akcakaya/