2016-11-11 62 views
1

我有一些問題,誤解Laravel SP(ServiceProvider)。我有抽象類庫和她的接口:DI,ServiceProvider,抽象父和Laravel 5.3

abstract class Repository implements RepositoryInterface { 

private $model; 
private $parser; 

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


interface RepositoryInterface { 

public function create(array $attributes); 
public function update($id, array $attributes); 
public function delete($id); 

public function all(); 
public function find($id); 
public function filter(array $parameters, $query=null); 
public function query(array $parameters, $query=null); } 

和例如一些孩子UserRepository:

class UserRepository extends Repository implements UserRepositoryInterface { 

protected $model_name = "App\Models\User"; 

public function __construct() { 
    parent::__construct(); 
} 

public function activation($user_id) { 
    return "user"; 
} 

public function deactivation($user_id) { 
    return "user"; 
} } 

和簡單ModelParser類:

class ModelParser { 

protected $parameters; 
protected $model; 

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

這項工作很好,但我會通過ModelParser作爲DI在我的抽象Repository構造與參數$model。我沒有想法。我應該怎麼做?

我用這樣的:

class UserController extends Controller { 

private $repository; 

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

回答

1

那麼它的有點,因爲你的ModelParser需要$model,因爲它的參數複雜。而且由於這個$model可能會因其存儲庫而異,如果我們試圖使用Laravel service container binding來解決它,它將會非常複雜。

有一個更簡單的方法,我們可以讓ModelParser類的構造函數接收可選的$model參數。然後,我們可以添加額外的方法來設置此$model屬性,像這樣:

namespace App\Models; 

class ModelParser 
{ 
    protected $parameters; 
    protected $model; 

    // Make $model parameter optional by providing default value. 
    public function __construct($model = null) { 
     $this->model = $model; 
    } 

    // Add setter method for $model. 
    public function setModel($model) 
    { 
     $this->model = $model; 

     return $this; 
    } 
} 

而現在,你可以注入ModelParser到您的抽象類Repository。 Laravel將很容易解決這個ModelParser參數

namespace App\Models; 

use App\Models\ModelParser; 
use App\Models\RepositoryInterface; 

abstract class Repository implements RepositoryInterface 
{ 
    private $model; 
    private $parser; 

    // Pass ModelParser instance to your constructor! 
    public function __construct(ModelParser $parser) 
    { 
     $this->model = new $this->model_name(); 

     // Set the parser's model property. 
     $this->parser = $parser->setModel($this->model); 
    } 

    // Rest of your code. 
} 

如果你擴展抽象類Repository,你仍然有這個ModelParser傳遞給構造函數,像這樣:其實

namespace App\Models; 

use App\Models\ModelParser; 
use App\Models\UserRepositoryInterface; 

class UserRepository extends Repository implements UserRepositoryInterface 
{ 
    protected $model_name = "App\Models\User"; 

    public function __construct(ModelParser $parser) 
    { 
     parent::__construct($parser); 
    } 
} 

,如果你」在類實例化過程中,不打算傳遞另一個參數或執行其他參數,只需從UserRepository中刪除__construct()方法並依賴其父項(摘要Repository)。

希望得到這個幫助!

+0

是的,這對我有很大的幫助。我以另一種方式做了,但我想用DI做點什麼。謝謝! – gargi258