douxian1892 2015-01-11 00:55
浏览 76
已采纳

Laravel模型观察者存储库注入

I'm trying to wrap my head around how to inject Laravel's model observers with repositories. Currently, I have this setup.

UserPetServiceProvider.php

<?php namespace Bunny\Providers;

use Illuminate\Support\ServiceProvider;
use Bunny\Observers\Pet\UserPetObserver;

class UserPetServiceProvider extends ServiceProvider {

    public function register()
    {
        // User pets
        $this->app->bind('Bunny\Repos\Pet\IUserPetRepo', 'Bunny\Repos\Pet\UserPetRepo');

        // User pet layers
        $this->app->bind('Bunny\Repos\Pet\IUserPetLayerRepo', 'Bunny\Repos\Pet\UserPetLayerRepo');

        // User pet markings
        $this->app->bind('Bunny\Repos\Pet\IUserPetMarkingRepo', 'Bunny\Repos\Pet\UserPetMarkingRepo');

        $this->app->events->subscribe(new UserPetObserver());
    }

}

It binds all the interfaces and repositories fine and would with the observer, but I need repository injection which I do in the constructor. Nothing is being passed in the constructor so it would explain why it fails.

UserPetRepo.php

<?php namespace Bunny\Repos\Pet;

use Bunny\Repos\BaseRepo;
use Bunny\Models\Pet\UserPet;
use Bunny\Repos\User\IUserRepo;
use Bunny\Repos\Breed\IStageRepo;
use Bunny\Repos\Breed\IBreedLayerRepo;

use Illuminate\Config\Repository as Config;
use Illuminate\Support\Str as String;
use Illuminate\Session\SessionManager as Session;
use Illuminate\Events\Dispatcher;

class UserPetRepo extends BaseRepo implements IUserPetRepo {

    public function __construct(UserPet $pet, IUserRepo $user, IStageRepo $stage, IBreedLayerRepo $layer, Config $config, String $string, Session $session, Dispatcher $events)
    {
        $this->model = $pet;
        $this->user = $user;
        $this->stage = $stage;
        $this->layer = $layer;
        $this->config = $config;
        $this->string = $string;
        $this->session = $session;
        $this->events = $events;

        $this->directory = $this->config->get('pathurl.userpets');
        $this->url       = $this->config->get('pathurl.userpets_url');
    }

    /**
     * Create new user pet
     * @param attributes     Attributes
     */
    public function createWithImage( array $attributes, array $colors, $domMarkings = null, $domMarkingColors = null, $recMarkings = null, $recMarkingColors = null )
    {
        $this->model->name = $attributes['name'];
        $this->model->breed_id = $attributes['breed_id'];
        $this->model->user_id = $this->user->getId();
        $this->model->stage_id = $this->stage->getBaby()->id;

        // Get image
        $image = $this->layer->compile(
            $attributes['breed_id'],
            'baby',
            $colors,
            $domMarkings,
            $domMarkingColors
        );

        // Write image and set
        $file = $this->writeImage( $image );
        if( ! $file )
        {
            return false;
        }

        $this->model->base_image = $file;
        $this->model->image = $file;

        if( ! $this->model->save() )
        {
            return false;
        }

        $this->events->fire('userpet.create', array($this->model));

        return $this->model;
    }

    /**
     * Write image
     * @param image      Imagick Object
     */
    protected function writeImage( $image )
    {
        $fileName = $this->string->random(50) . '.png';

        if( $image->writeImage( $this->directory . $fileName ) )
        {
            return $fileName;
        }

        $this->model->errors()->add('writeImage', 'There was an error writing your image. Please contact an administrator');
        return false;
    }

}

UserPetObserver.php

use Bunny\Repos\Pet\IUserPetLayerRepo;
use Bunny\Repos\Pet\IUserPetMarkingRepo;
use Bunny\Observers\BaseObserver;

class UserPetObserver extends BaseObserver {

    public function __construct(IUserPetLayerRepo $layers, IUserPetMarkingRepo $markings)
    {
        $this->layers = $layers;
        $this->markings = $markings;
    }

    /**
     * After create
     */
    public function onCreate( $model )
    {
        $this->layers->user_pet_id = $model->id;
        dd(Input::all());
        $this->layers->breed_layer_id = $model->id;
    }

    public function subscribe( $event )
    {
        $event->listen('userpet.create', 'UserPetObserver@onCreate');
    }

}

It throws this as the error:

Argument 1 passed to Bunny\Observers\Pet\UserPetObserver::__construct() must be an instance of Bunny\Repos\Pet\IUserPetLayerRepo, none given, called in H:\WD SmartWare.swstor\HALEY-HP\Source2\bunny-meadows\app\Bunny\Providers\UserPetServiceProvider.php on line 22 and defined

Which makes sense since I'm not passing anything in the constructor. So I try to pass my repository manually.

$this->app->events->subscribe(new UserPetObserver(new UserPetLayerRepo, new UserPetMarkingRepo));

But then it throws errors of UserPetLayerRepo needing injections... and it just chains on and on. Is there anyway of doing this that I'm just overthinking?

Thanks.

EDIT::: This is the only thing I could think of doing. This seems like a really ugly/bad way of doing it though:

$this->app->events->subscribe(new UserPetObserver($this->app->make('Bunny\Repos\Pet\UserPetLayerRepo'), $this->app->make('Bunny\Repos\Pet\UserPetMarkingRepo')));

Any other ideas?

  • 写回答

1条回答 默认 最新

  • dongshanya2008 2015-01-11 02:33
    关注

    Try just:

    $this->app->events->subscribe($this->app->make('UserPetObserver'));
    

    When Laravel makes the UserPetObserver object, it will read the type-hinted dependencies in the constructor and automatically make them, as well.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制