2017-11-25 301 views
0

我对Laravel比较新,我创建了一个中间件和策略来处理我的项目中的'Ownable'雄辩对象。Laravel依赖注入基类

我该使用特点做:

trait Ownable 
{ 

    public function user(){ 
     return $this->belongsTo(User::class, 'created_by'); 
    } 
} 

在我的政策,我只是这样做:

class RightPolicy 
{ 
    use HandlesAuthorization; 

    public function update(User $user, Ownable $ownable) 
    { 
     return $ownable->created_by == $user->id; 
    } 
} 

而我的中间件,在我的控制器分配到正确的动作:

class CheckRights 
{ 
    public function __construct(Route $route, Ownable $object) { 
     $this->route = $route; 
     $this->object = $object; 
    } 

    public function handle($request, Closure $next) 
    { 
     // @TODO handle request 
    } 
} 

然后我创建了一个使用Ownable特征的类:

class Thread extends Model 
{ 
    use Ownable; 
} 

然而,当我尝试运行具有这种结构的项目,Laravel的依赖注入trhows错误:

Target [App\Ownable] is not instantiable while building App\Http\Middleware\CheckRights

有没有办法让依赖注入知道实例权类(可能使用路线或别的东西)?

如果没有,是否有一个方便的方式来做别的事情,而不依赖注入器来确保正确的类被实例化?

+0

根据定义,特征不是可实例化的。我不认为你需要特质在这里,它更多关于类和扩展 –

+0

我明白,我在这里使用特征为多态性原因。一个线程是可持有的,但也是可以评论的,但是,一个ForumRule不是可持有的,但是可以评论(例如)。这就是我选择这种结构的原因。 @VincentDecaux – Joas

+0

使用Trait的结果总是可以作为有效的类自行编写出来。当Laravel在该特性中应用自动解析时,它会尝试初始化哪个不起作用。因此,如果你想要达到你想要的水平,你的方法是转换到一个班级,而不是在这里使用特质。 –

回答

0

我使用AppServiceProvider中的app :: bind方法解决了这个问题。

在服务提供者的注册方法中,我将App \ Ownable接口绑定到一个函数,该函数将所有注入的Eloquent对象传递给路由器。

namespace App\Providers; 

use App\Ownable; 
use Illuminate\Support\Facades\Route; 
use Illuminate\Support\ServiceProvider; 
use Illuminate\Support\Facades\Schema; 

class AppServiceProvider extends ServiceProvider 
{ 
    public function boot() 
    { 
     Schema::defaultStringLength(191); 
    } 

    public function register() 
    { 
     // Binding ownable trait/interface for correctly handling policy 
     $this->app->bind('App\Ownable', function() { 
      // Get all parameters passed to the current route 
      $array = Route::getCurrentRoute()->parameters; 

      $return = NULL; 
      foreach ($array as $object){ 
       if ($object instanceof Ownable){ 
        // Fetch the last ownable instance found passed to the route 
        $return = $object; 
       } 
      } 

      // return it 
      return $return; 
     }); 
    } 
} 

了解更多关于:Binding

然后我再加上正确typehinting的接口可拥有特质,作为一个论坛上提出的其他网站上:在我的中间件

class Thread extends Model implements \App\Interfaces\Ownable 
{ 
    use Ownable; 
} 

然后构造函数我使可选参数成为可选参数(用于在调用存储或创建动作时未给出对象)并基于动作名称处理我的请求并且如果给定对象

class CheckRights 
{ 
    public function __construct(Route $route, Ownable $object = null) { 
     $this->route = $route; 
     $this->object = $object; 
    } 

    public function handle($request, Closure $next) 
    { 
     // Get the controller's action name 
     $action = $this->route->getActionName(); 
     $action = substr($action, strpos($action, '@') + 1); 

     // Check if an object is given in the request 
     if ($action != 'store' && $action != 'create' && isset($this->object)){ 
      // Check if gate allows user to update/delete object 
      if ($request->user()->can($action, $this->object)){ 
       return $next($request); 
      } 
     }elseif($action == 'store' || $action == 'create'){ 
      // Check if gate allows user to create object 
      if ($request->user()->can($action, Ownable::class)){ 
       return $next($request); 
      } 
     } 

     return back(); 
    } 
}