Laravel -使用仓库模式

0s0u357o  于 2023-05-19  发布在  其他
关注(0)|答案(3)|浏览(170)

我正在尝试学习存储库模式,并且似乎对如何在渴望加载关系并将数据库逻辑保持在控制器之外时使用此存储库模式感到有点困惑。
我的存储库/应用程序结构的快速概述。

app/
  Acme/
    Repositories/
      RepositoryServiceProvider.php
      Product/
        EloquentProduct.php
        ProductInterface.php
      Category/
        EloquentCategory.php
        CategoryInterface.php

示例ProductInterface.php

<?php namespace GD\Repositories\Product;

interface ProductInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

CategoryInterface.php示例

<?php namespace GD\Repositories\Category;

interface CategoryInterface
{
    public function all();

    public function find($id);

    public function findBySlug($slug);
}

好了,简单的部分是使用DI将模型依赖注入控制器。
列出所有类别相关的产品更加困难,因为我不再使用雄辩的模型。我正在使用一个界面,它没有暴露所有雄辩的方法。
如果我不在我的EloquentCategory类中实现一个with方法,这将无法工作...

public function show($slug)
{
  return Response::json($this->category->findBySlug($slug)->with('products'), 200);
}

我是否应该创建一个单独的服务类来将两个存储库粘合在一起?例如,允许以下

public function __construct(ShopService $shop)
{
  $this->shop = $shop;
}

public function show($slug)
{
  return Response::json( $this->shop->getProductsInCategory($slug), 200 );
}

或者,我应该在我的类别存储库中实现with方法吗?

public function with($relation)
{
  return Category::with($relation);
}

最后,我对仓库模式用法的理解是否正确?

v6ylcynt

v6ylcynt1#

你想多了,repository只是你的controllermodel之间的一个链接/桥梁,因此controller直接使用repository类而不是model,在那个repository中,你可以从那里使用model声明你的方法,例如:

<?php namespace GD\Repositories\Category;

interface CategoryInterFace{

    public function all();

    public function getCategoriesWith($with);

    public function find($id);
}

现在在repository类中实现接口:

<?php namespace GD\Repositories\Category;

use \EloquentCategory as Cat; // the model
class CategoryRepository implements CategoryInterFace {
    public function all()
    {
        return Cat::all();
    }

    public function getCategoriesWith($with)
    {
        return Cat::with($with)->get();
    }

    public function find($id)
    {
        return Cat::find($id):
    }
}

要在控制器中使用它,请执行以下操作:

<?php

use GD\Repositories\Category\CategoryInterFace;

class CategoryController extends BaseController {

    public function __construct(CategoryInterFace $category)
    {
        $this->cat = $category;
    }

    public function getCatWith()
    {
        $catsProd = $this->cat->getCategoriesWith('products');
        return $catsProd;
    }

    // use any method from your category
    public function getAll()
    {
        $categories = $this->cat->all();

        return View::make('category.index', compact('categories'));
    }

}

**注意:**省略了仓库的IoC绑定,因为这不是您的问题,您知道这一点。
**更新:**我在这里写了一篇文章:LARAVEL -使用存储库模式。

6psbrbz9

6psbrbz92#

有一个非常简单的方法来做到这一点,它是深入探讨在这个环节
http://heera.it/laravel-repository-pattern#.U6XhR1cn-f4
我一直在寻找确切的解决方案,到目前为止,它运行良好
所以你的想法是在你的仓库代码中声明它

public function __construct(\Category $category)
{
    $this->category = $category;
} 
public function getAllUsers()
{
    return $this->category->all();
}

public function __call($method, $args)
{
    return call_user_func_array([$this->category, $method], $args);
}

当某些函数丢失时,强制调用模型

js81xvg6

js81xvg63#

在UnitController.php控制器中

<?php

namespace App\Http\Controllers\General;

use App\Contracts\General\UnitInterface;
use App\Traits\ApiResponser;
use App\Http\Controllers\Controller;

class UnitController extends Controller
{
    use ApiResponser;

    protected $unit;

    public function __construct(UnitInterface $unit)
    {
        $this->unit = $unit;
    }

    public function unitList()
    {
        $units = $this->unit->all();
        return $this->set_response(['units' => $units],  200, 'success', ['Unit list']);
    }
    
}

在UnitInterface.php界面

<?php
namespace App\Contracts\General;
interface UnitInterface
{
    public function all();
}

在UnitRepository.php存储库中

<?php
namespace App\Repositories\General;
use App\Models\General\Unit;
use App\Contracts\General\UnitInterface;

class UnitRepository implements UnitInterface
{
    public function all()
    {
        return Unit::all();
    }
}

在RepositoriesServiceProvider.php中自定义服务提供者绑定Interface & Concrete类(Repository)

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;

class RepositoriesServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind('App\Contracts\General\UnitInterface', 'App\Repositories\General\UnitRepository');
    }
}

在app.php中

<?php
return [
    'providers' => [
        // Custom Service Providers...
        App\Providers\RepositoriesServiceProvider::class,
    ],
];

相关问题