2014-04-30 45 views
4

我有一个试图调试我的代码的问题,据我所见,查看代码的各个位,它都链接正确,但这里一定有些东西显而易见。传递给构造函数的参数必须是接口的实例,装饰器的实例给出

对于我在这里粘贴的问题的代码量我感到很遗憾,但不幸的是,有很多文件正在为应用程序的单个实体播放,我认为提供更多而不是更好减。

首先错误消息:

Argument 1 passed to Raid\Composers\PreferenceDataComposer::__construct() must be an instance of Raid\Repo\User\PreferenceInterface, instance of Raid\Repo\Preference\CacheDecorator given, called in C:\wamp\www\raid\app\Raid\Composers\ComposerServiceProvider.php on line 34 and defined 

所以首先,在正在生成我是View Composer的这个错误:

<?php namespace Raid\Composers; 

use Raid\Repo\User\PreferenceInterface; 

class PreferenceDataComposer { 

    protected $preference; 

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

    public function compose($view) 
    {  
     $view->with('preferences', $this->preference->getActive()); 
    } 

} 

,然后服务提供商的作曲家:

<?php namespace Raid\Composers; 

use Illuminate\Support\ServiceProvider; 

class ComposerServiceProvider extends ServiceProvider { 

    public function register() 
    { 
     $this->app->bind('Raid\Composers\PreferenceDataComposer', function($app) 
     { 
      return new PreferenceDataComposer(
       $this->app->make('Raid\Repo\Preference\PreferenceInterface') 
      ); 
     }); 
    } 

    public function boot() 
    { 
     $this->app->view->composer('account.preferences', 'Raid\Composers\PreferenceDataComposer'); 
    } 

} 

接下来是接口:

<?php namespace Raid\Repo\Preference; 

interface PreferenceInterface { 

    public function getActive(); 

} 

而且CacheDecorator:

<?php namespace Raid\Repo\Preference; 

use Raid\Service\Cache\CacheInterface; 

class CacheDecorator extends AbstractPreferenceDecorator implements PreferenceInterface { 

    protected $cache; 

    public function __construct(PreferenceInterface $preference, CacheInterface $cache) 
    { 
     parent::__construct($preference); 
     $this->cache = $cache; 
    } 

    public function getActive() 
    { 
     $key = md5('active'); 

     if ($this->cache->has($key)) { 
      return $this->cache->get($key); 
     } 

     $preferences = $this->preference->getActive(); 

     $this->cache->put($key, $preferences); 

     return $preferences; 
    } 
} 

和抽象的装饰:

<?php namespace Raid\Repo\Preference; 

abstract class AbstractPreferenceDecorator implements PreferenceInterface { 

    protected $preference; 

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

} 

那么我们有仓库:

<?php namespace Raid\Repo\Preference; 

use Raid\Repo\AbstractRepo; 
use Illuminate\Database\Eloquent\Model; 
use Raid\Service\Log\LogInterface; 
use Raid\Service\Email\EmailInterface; 

class EloquentPreference extends AbstractRepo implements PreferenceInterface { 

    protected $preference; 
    protected $preferenceType; 
    protected $log; 
    protected $email; 

    public function __construct(Model $preference, Model $preferenceType, LogInterface $log, EmailInterface $email) 
    { 
     $this->preference = $preference; 
     $this->preferenceType = $preferenceType; 
     $this->log = $log; 
     $this->email = $email; 
    } 

    public function getActive() 
    { 
     return $this->preference->whereActive()->get(); 
    } 

} 

,然后雄辩型号本身:

<?php 

class Preference extends Eloquent { 

    protected $table = 'preferences'; 
    protected $guarded = array('id'); 
    protected $softDelete = true; 

    public function scopeWhereActive($query) 
    { 
     return $query->where('active', '=', '1'); 
    } 

} 

,然后结合接口和回购服务提供商:

<?php namespace Raid\Repo; 

use Preference; 
use PreferenceType; 
use Raid\Service\Cache\FileCache; 
use Raid\Repo\Preference\CacheDecorator as PreferenceCacheDecorator; 
use Raid\Repo\Preference\EloquentPreference; 
use Illuminate\Support\ServiceProvider; 

class RepoServiceProvider extends ServiceProvider { 

    public function register() 
    { 
     $app = $this->app; 

     $app->bind('Raid\Repo\Preference\PreferenceInterface', function($app) 
     { 
      $preference = new EloquentPreference(
       new Preference, 
       new PreferenceType, 
       $app->make('Raid\Service\Log\LogInterface'), 
       $app->make('Raid\Service\Email\EmailInterface') 
      ); 

      return new PreferenceCacheDecorator(
       $preference, 
       new FileCache($app['cache'], 'preferences', 1440) 
      ); 
     }); 
    } 

} 

在上面的代码,你可以在作曲看到的,我问了接口的实例,并在作曲家的服务提供者,我将其实例从IoC中解析出来。

在repo服务提供程序中,我通过制作repo实例(传入其依赖项)来绑定接口,然后返回由缓存修饰器包装的repo。所有的回购,装饰,抽象装饰实现接口,所以我不知道它是如何被解析为不是接口的实例?

任何帮助你可以给与调试将是我美妙的。

如果您需要进一步的代码,请留言。

+0

这是Raid \ Composers \ ComposerServiceProvider.php 34行? – egig

+0

它是问题中的第二个代码块,第34行是返回新的PreferenceDataComposer的行:'返回新的PreferenceDataComposer($ this-> app-> make('Raid \ Repo \ Preference \ PreferenceInterface'));' – Mortelugo

+0

@egig(忘记标签之前抱歉)。我可以提供的任何其他数据/代码可能有助于阐明这一点?真的让我难倒 – Mortelugo

回答

2

你的问题可能在Raid \ Repo \ User \ PreferenceInterface中,它应该是Raid \ Repo \ Preference \ PreferenceInterface。

除此之外,我不能真正在代码中看到问题,为了测试我创建了一些名称空间,接口和类,但是PreferenceDataComposer实例化,对我没有任何问题。

在我routes.php我创建一个路由实例化,创建基于口才班,一些必要的绑定,手动注册服务提供商和加载命名空间的文件:

<?php 

class Preference extends Eloquent { 

    protected $table = 'preferences'; 
    protected $guarded = array('id'); 
    protected $softDelete = true; 

    public function scopeWhereActive($query) 
    { 
     return $query->where('active', '=', '1'); 
    } 

} 

class PreferenceType extends Eloquent { 

    protected $table = 'preferences'; 
    protected $guarded = array('id'); 
    protected $softDelete = true; 

    public function scopeWhereActive($query) 
    { 
     return $query->where('active', '=', '1'); 
    } 

} 

App::bind('Raid\Service\Log\LogInterface', 'Raid\Service\Log\Log'); 
App::bind('Raid\Service\Email\EmailInterface', 'Raid\Service\Email\Email'); 
App::bind('Raid\Service\Cache\CacheInterface', 'Raid\Service\Cache\FileCache'); 

require app_path().'/Mortelugo.php'; 

Route::any('test', function() { 

    $repo = new Raid\Repo\RepoServiceProvider(App::make('app')); 
    $repo->register(); 

    $composer = new Raid\Composers\ComposerServiceProvider(App::make('app')); 
    $composer->register(); 

    $preference = App::make('Raid\Composers\PreferenceDataComposer'); 

    // This is it instantiated 

    dd($preference); 

}); 

我创建了一个Mortelugo.php文件,所有的命名空间,但我不得不创建一些缺少的,并改变其中一个命名不正确的:

<?php 

namespace Raid\Composers { 

    use Raid\Repo\Preference\PreferenceInterface; 

    class PreferenceDataComposer { 

     protected $preference; 

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

     public function compose($view) 
     {  
      $view->with('preferences', $this->preference->getActive()); 
     } 

    } 

} 

namespace Raid\Composers { 

    use Illuminate\Support\ServiceProvider; 

    class ComposerServiceProvider extends ServiceProvider { 

     public function register() 
     { 
      $this->app->bind('Raid\Composers\PreferenceDataComposer', function($app) 
      { 
       return new PreferenceDataComposer(
        $this->app->make('Raid\Repo\Preference\PreferenceInterface') 
       ); 
      }); 
     } 

     public function boot() 
     { 
      $this->app->view->composer('account.preferences', 'Raid\Composers\PreferenceDataComposer'); 
     } 

    } 

} 

namespace Raid\Repo { 

    use Preference; 
    use PreferenceType; 
    use Raid\Service\Cache\FileCache; 
    use Raid\Repo\Preference\CacheDecorator as PreferenceCacheDecorator; 
    use Raid\Repo\Preference\EloquentPreference; 
    use Illuminate\Support\ServiceProvider; 

    abstract class AbstractRepo { 

    } 

    class RepoServiceProvider extends ServiceProvider { 

     public function register() 
     { 
      $app = $this->app; 

      $app->bind('Raid\Repo\Preference\PreferenceInterface', function($app) 
      { 
       $preference = new EloquentPreference(
        new Preference, 
        new PreferenceType, 
        $app->make('Raid\Service\Log\LogInterface'), 
        $app->make('Raid\Service\Email\EmailInterface') 
       ); 

       return new PreferenceCacheDecorator(
        $preference, 
        new FileCache($app['cache'], 'preferences', 1440) 
       ); 
      }); 
     } 

    } 

} 

namespace Raid\Repo\Preference { 

    interface PreferenceInterface { 

     public function getActive(); 

    } 

    use Raid\Service\Cache\CacheInterface; 

    abstract class AbstractPreferenceDecorator implements PreferenceInterface { 

     protected $preference; 

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

    } 


    class CacheDecorator extends AbstractPreferenceDecorator implements PreferenceInterface { 

     protected $cache; 

     public function __construct(PreferenceInterface $preference, CacheInterface $cache) 
     { 
      parent::__construct($preference); 
      $this->cache = $cache; 
     } 

     public function getActive() 
     { 
      $key = md5('active'); 

      if ($this->cache->has($key)) { 
       return $this->cache->get($key); 
      } 

      $preferences = $this->preference->getActive(); 

      $this->cache->put($key, $preferences); 

      return $preferences; 
     } 
    } 

    use Raid\Repo\AbstractRepo; 
    use Illuminate\Database\Eloquent\Model; 
    use Raid\Service\Log\LogInterface; 
    use Raid\Service\Email\EmailInterface; 

    class EloquentPreference extends AbstractRepo implements PreferenceInterface { 

     protected $preference; 
     protected $preferenceType; 
     protected $log; 
     protected $email; 

     public function __construct(Model $preference, Model $preferenceType, LogInterface $log, EmailInterface $email) 
     { 
      $this->preference = $preference; 
      $this->preferenceType = $preferenceType; 
      $this->log = $log; 
      $this->email = $email; 
     } 

     public function getActive() 
     { 
      return $this->preference->whereActive()->get(); 
     } 

    } 

} 

namespace Raid\Service\Log { 

    interface LogInterface { 

    } 

    class Log implements LogInterface { 

    } 

} 

namespace Raid\Service\Email { 

    interface EmailInterface { 

    } 

    class Email implements EmailInterface { 

    } 

} 

namespace Raid\Service\Cache { 

    interface CacheInterface { 

    } 

    class FileCache implements CacheInterface { 

    } 

} 
+1

确实,这是问题,不正确的命名空间。我真的应该切换到IDE,以便像这样的东西自动指向我! – Mortelugo

+0

我目前正在享受PHPStorm 8(测试版),确实有助于解决这类错误,并做了很多工作,为您编写了大部分样板代码并帮助您重构。 –

1

找到终于问题 - 由于@rizqi上#laravel,对我的看法作曲家,我使用了错误的命名空间:

use Raid\Repo\User\PreferenceInterface; 

应该

use Raid\Repo\Preference\PreferenceInterface; 
相关问题