2014-09-02 1 views
4

네임 스페이스 ...에서 :Laravel 자동 해상도 IOC - 컨트롤러에서 작동하지만 내가 설정/app.php에 다음과 같은 서비스 제공을 작성하고 등록</p> <p>간결함을 위해 생략 사용자 정의 클래스

class OfferServiceProvider extends ServiceProvider 
{ 
    public function register() 
    { 
     $this->registerLossControlManager(); 
    } 

    protected function registerLossControlManager() 
    { 
     $this->app->bind('LossControlInterface', 'LossControl'); 
    } 
} 

여기 내 LossControlInterface

interface LossControlInterface 
{ 
    /** 
    * @param int $demandId 
    * @param float $offerTotal 
    * @param float $productTotal 
    * @param null|int $partnerId 
    * @return mixed 
    */ 
    public function make($demandId, $offerTotal, $productTotal, $partnerId = null); 

    /** 
    * @return float 
    */ 
    public function getAcceptableLoss(); 

    /** 
    * @return bool 
    */ 
    public function isAcceptable(); 

    /** 
    * @return bool 
    */ 
    public function isUnacceptable(); 

    /** 
    * @return null 
    */ 
    public function reject(); 
} 

컨트롤러 내에서 지금이다 다음과 같이 나는 LossController를 삽입 할 수 있습니다

012 3,516,
use LossControlInterface as LossControl; 

class HomeController extends BaseController { 
    public function __construct(LossControl $lossControl) 
    { 
     $this->lossControl = $lossControl; 
    } 

    public function getLossThresholds() 
    { 
     $lossControl = $this->lossControl->make(985, 1000, null); 

     var_dump('Acceptable Loss: ' . $lossControl->getAcceptableLoss()); 
     var_dump('Actual Loss: ' . $lossControl->calculateLoss()); 
     var_dump('Acceptable? ' . $lossControl->isAcceptable()); 

    } 
} 

그러나 나는 명령에 의해 호출 사용자 정의 클래스 내에서 LossControlInterface을 의존성 삽입하려고하면 :

[2014-09-02 13:09:52] development.ERROR: exception 'ErrorException' with message 'Argument 11 passed to Offer::__construct() must be an instance of LossControlInterface, none given, called in /home/vagrant/Code/.../ProcessOffer.php on line 44 and defined' in /home/vagrant/Code/.../Offer.php:79 

내가 사용자 정의 클래스로 인터페이스를 의존성 삽입 할 수 없습니다 나는 것처럼 보이지만, I 컨트롤러에 종속성을 주입 할 수 있습니다.

무엇이 잘못되었거나 생략했는지에 대한 의견이 있으면 자동 해결이 작동합니까?

+0

사용자 정의 클래스를 작성하는 코드를 게시 할 수 있습니까? 또한 서비스 제공 업체 또는 장인의 명령 내에서 생성됩니까? –

+0

artisan 명령 내에서 만들어집니다. 명령/ProcessOffer.php :'비공개 함수 setOffer (Offer $ offer = null) {$ this-> processOffer = $ offer? : new Offer();}' – Gravy

답변

9

IoC는 컨트롤러 내에서 자동으로 실행되며 Laravel이 컨트롤러 구성을 처리하기 때문에 주사가 표시되지 않습니다. 사용자 정의의 생성을 깔대기에 의해, 정도,

$myClass = new ClassWithDependency(app()->make('Dependency')); 

당신은이를 숨길 수 있습니다 다음 new 키워드를 사용하여 다른 사용자 정의 클래스를 만들 때, 당신은 아직도 그것의 생성자에 필요한 모든 매개 변수에 보내야합니다 당신이 그것을 필요로 할 때마다

// Your service provider 
public function register() 
{ 
    $this->app->bind('ClassWithDependency', function($app) { 
     return new ClassWithDependency($app->make('Dependency')); 
    }); 
} 

그런 다음 바로 IOC의 그것을 만들했습니다 : 서비스 공급자를 통해 클래스 귀하의 경우에는

$myClass = app()->make('ClassWithDepenency'); 

을, 당신은 변경할 수 있습니다 코드는 다음과 같이합니다 :

private function setOffer(Offer $offer = null) { 
    $this->processOffer = $offer ?: 
     new Offer(app()->make('LossControlInterface')); 
} 

아마 청소기 접근 방식은 서비스 제공 업체 및 컨트롤러에 주입 누가 받 OfferFactory을 만들 수 있습니다. 컨트롤러는 다음이 필요할 때마다 제안을 만들기 위해 공장을 요청할 수 있습니다 하나이 완전히 제안의 창조 뒤에 로직 컨트롤러 디커플링, 아직이 자리에있을 수 있도록하는 이점을 갖고있다

// Controller 
public function __construct(OfferFactory $offerFactory) 
{ 
    $this->offerFactory = $offerFactory; 
} 

public function setOffer(Offer $offer = null) 
{ 
    $this->processOffer = $offer ?: $this->offerFactory->createOffer(); 
} 

// OfferFactory 
class OfferFactory 
{ 
    public function createOffer() 
    { 
     return app()->make('Offer'); 
    } 
} 

제안을 만드는 과정에 필요한 복잡성을 추가하십시오.

Laravel 5.2에서
1

특정 문제에 대한 가장 간단한 해결책은

App::make('Offer'); 

또는 짧은에

new Offer(); 

을 대체하는 것입니다 걸릴 Laravel 컨테이너를 사용합니다

app('Offer'); 

의존성의 배려.

당신이 Offer 생성자에 추가 매개 변수를 전달하려는, 그러나 그것은 서비스 제공 업체

App::bind('Offer', function($app, $args) { 
    return new Offer($app->make('LossControl'), $args); 
}); 

그리고 짜잔에 바인딩 할 필요가있는 경우, 지금은 laravel 5.4에서

app('Offer', [123, 456]); 
0

을 쓸 수 있습니다 (https://github.com/laravel/framework/pull/18271) IoC 컨테이너의 새로운 makeWith 메서드를 사용해야합니다.

App::makeWith('App\MyNameSpace\MyClass', [ $id ]); 

5.3 이하를 사용하는 경우 위의 답변이 적용됩니다.

관련 문제