传递给构造函数的参数必须是接口的实例,给定的decorator的实例


Arguement passed to constructor must be an instance of interface, instance of decorator given

我在调试代码时遇到了一个问题,据我所见,从代码的各个部分来看,它都正确地连接在一起,但这里肯定缺少一些明显的东西。

很抱歉我在这里粘贴了大量的代码,但不幸的是,对于应用程序的单个实体,有很多文件在运行,我认为最好提供更多而不是更少。

首先是错误消息:

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

因此,首先,我的视图编辑器是这个错误产生的地方:

<?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)
            );
        });
    }
}

在上面的代码中,你可以在Composer中看到,我请求接口的一个实例,在Composer的服务提供商中,我从IoC中解析它的一个例子。

在回购服务提供程序中,我通过创建回购的实例(传递其依赖项(来绑定接口,然后返回用缓存装饰器包装的回购。所有的repo、decorator、抽象decorator都实现了接口,所以我不确定它是如何被解析为不是接口的实例的?

你能在调试方面提供的任何帮助都将是我的荣幸。

如果你需要更多的代码,请大声喊。

您的问题可能出现在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 {
    }
}

终于发现了这个问题-多亏了#laravel上的@rizqi,在我的视图编辑器上,我使用了错误的命名空间:

use Raid'Repo'User'PreferenceInterface;

应该是

use Raid'Repo'Preference'PreferenceInterface;