如何在Laravel中创建一个使用需要多个存储库的类的外观?

时间:2017-05-02 06:42:29

标签: laravel-5 packages facade service-provider contract

我已经使用Laravel差不多一年了,但是我非常擅长创建自己的软件包并使用合同,存储库,外墙等......所以请耐心等待。

如果我正在服务提供商中正确注册外观,我遇到了问题。这是上下文(假设命名空间和导入已经正确完成。我不包括它们,所以这不会太复杂):

我想创建一个名为AdminServices的外观来访问名为AdminServices的类:

class AdminServices implements AdminServicesContract
{
    private $check;

    public function __construct(CheckAdminContract $check)
    {
        $this->check = $check;
    }

    public function check()
    {
        return $this->check;
    }
}

您会注意到此课程需要合同CheckAdminContract。此合同在CheckAdmin类中实现。请注意,此类需要UserRepository:

class CheckAdmin implements CheckAdminContract
{

    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function userIsAdmin(User $user)
    {
        return $user->roles()->whereAdmin()->count() > 0;
    }

    public function userIsAdminById($user_id)
    {
        $user = $this->userRepository->getById($user_id);
        return $this->userIsAdmin($user);
    }

    public function userIsSuperAdmin(User $user)
    {
        return $user->roles()->whereSuperAdmin()->count() > 0;
    }

    public function userIsSuperAdminById($user_id)
    {
        $user = $this->userRepository->getById($user_id);
        return $this->userIsSuperAdmin($user);
    }
}

这是UserRepository:

interface UserRepository
{
    public function getById($user_id);
}

这是实现UserRepository的EloquentUserRepository:

class EloquentUserRepository implements UserRepository
{
    private $model;

    public function __construct()
    {
        $this->model = new User;
    }

    public function getById($user_id)
    {
        return $this->model->findOrFail($user_id);
    }
}

这是我要注册的Facade:

use Illuminate\Support\Facades\Facade;

class AdminServices extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'admin-services';
    }
}

以下是我在服务提供商处注册的内容(所有类都是通过使用指令正确导入的):

public function register()
{
    $this->app->singleton(UserRepository::class, EloquentUserRepository::class);
    $this->app->singleton(CheckAdminContract::class, CheckAdmin::class);
    $this->app->singleton(AdminServicesContract::class, AdminServices::class);
    $this->app->singleton('admin-services', function(){
        $userRepository = new EloquentUserRepository();
        $checkAdmin = new CheckAdmin($userRepository);
        return new AdminServices($checkAdmin);
    });
}

所以这是我的大问题:

在注册Facade访问器时,是否真的必须显式实例化所有存储库和契约实现?我已经将它们注册为上面的单身人士,所以在我天真的想法中,我相信再次实例化这些事情将会重新开始工作,如果我决定使用这些合同和存储库的不同实现,那么我会不止一次地改变它们,这在我天真的想法中似乎我做错了什么。

如果我确实在外观存取器的单件中正确地执行此操作,请告诉我吗?你能建议一种方法,你已经做了类似或更好的方法吗?

另外,如果你发现我没有正确地做某事或者我的代码编写得不好,请告诉我如何改进。同样,我对这些话题都很陌生,但我觉得我对它们有足够的了解,可以做得恰到好处。但我真的希望得到一些反馈意见,以免我做错了(如果我做错了)。

此外,如果我有更好的方式来构建或提出这个问题,请再次告诉我,以免我不止一次犯同样的错误。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我找到了自己问题的答案!

注册Facade时,我需要使用闭包中的$ app参数来创建CheckAdminContract(这完全消除了对此特定服务提供者中UserRepository的任何确认):

$this->app->singleton('admin-services', function($app) {
    $checkAdmin = $app->make(CheckAdminContract::class);
    return new AdminServices($checkAdmin);
});