Внедрение зависимостей Laravel Lucid Architecture
Я новичок в Lucid Architecture
применяется с Laravel
,
Я пытаюсь найти лучший способ добавить зависимости в мои функции. Вот функция страницы моих пользователей:
class UsersPageFeature extends Feature {
public function handle( Request $request,User $user ) {
$data = [];
$users = $this->run( GetUsersJob::class,['userModel'=> $user );
$data['users'] = $users;
return $this->run( new RespondWithViewJob( "web::pages.users.page", $data) );
}
}
И мой GetUsersJob
:
class GetUsersJob extends Job {
public function __construct($user) {
$this->user = $user;
}
public function handle( ) {
return $user->all();
}
}
Это работает, однако, мне нужно передать все зависимости для каждой работы. Я думаю, что это можно сделать лучше.
Пожалуйста, предложите лучший способ.
1 ответ
Вы правы, ваши фрагменты кода могут быть улучшены. Прежде всего, давайте проясним некоторые понятия, я также, возможно, не на 100% прав, это только мое понимание этой архитектуры.
Работа - это единственное атомное действие, которое должно отвечать только за одну вещь. Задания могут быть легко использованы повторно, они похожи на крошечные строительные блоки вашего приложения.
Функция обычно содержит несколько заданий и обслуживает запросы на конкретную услугу.
Я бы предложил использовать the Repository pattern
, В вашем примере вы передаете класс модели, и это немного сбивает с толку с семантической точки зрения.
Я делюсь своим BaseRepository
класс, вы можете использовать его - https://gist.github.com/CROSP/de909251feaa1c29bfd39336bc5aa4db
В вашем случае вы можете создать интерфейс под названием UserRepositoryContract
одним методом:
interface UserRepositoryContract extends BaseRepository {
function getAllUsers();
}
И реализовать это так, расширяя базовый класс репозитория и реализуя контракт:
class UsersRepository extends Repository implements UserRepositoryContract {
public function __construct( User $model ) {
parent::__construct( $model );
}
function getAllUsers() {
return $this->all();
}
}
Следующий момент заключается в том, что вы можете напрямую внедрить зависимости в классы заданий, если они были ранее зарегистрированы в контейнере DI (с использованием сервис-провайдеров):
class DataRepositoriesProvider extends ServiceProvider {
public function register() {
$this->app->singleton( UserRepositoryContract::class, UsersRepository::class );
}
}
Итак, в вашем классе Job вы можете просто иметь следующий код:
class GetUsersJob extends Job {
public function handle( UserRepositoryContract $userRepo) {
return $userRepo->all();
}
}
Надеюсь, что это имеет смысл и поможет вам лучше понять архитектуру.