mercredi 21 février 2018

Dependancy injection is making my code ugly

For testability we use DI, however I have a problem. Anytime I want to call something my code now looks ugly. I’m trying to understand how to avoid having to pass all the dependencies into a constructor, yet still maintain testability.

For example, lets imagine a service class to perform passport checks

Person < holds person data
PassportCheckService < enables us to perform check
PassportCheckRequest < holds params and any logic such as validation
PassportCheckSoapClient < php soap client with options specific to request
PassportCheckResponse < the response object
PersonDocumentService < save documents for a person

the class

class PassportCheckService {
    protected $person;
    protected $request;
    protected $response;
    protected $client;
    protected $personDocumentService;

    // constructor
    public function __construct(
        Person                  $person,
        PassportCheckRequest    $request,
        PassportCheckResponse   $response,
        PassportCheckSoapClient $client,
        PersonDocumentService   $personDocumentService
    ) {
        $this->person               = $person;
        $this->request                  = $request;
        $this->response                 = $response;
        $this->client                   = $client;
        $this->personDocumentService    = $personDocumentService;
    }

    // perform service
    public function execute() : PassportCheckResponse
    {
        // make call & build response instance
        $this->response->build($this->client->performCall($this->request));

        // save document
        if ($this->response->isSuccessStatus() &&
            $this->response->hasSavableDocument()
        ) {
            $this->personDocumentService->saveDocument(
                $this->person,
                $this->response->getDocumentFilename(),
                $this->response->getDocumentContents(),
                $this->response->getDocumentMime()
            );
        }

        // return response
        return $this->response;
    }
}

The problem is in order to call this service I have to pass in the dependancies:

$passportCheckService = new PassportCheckService(
    $person,
    $request,
    new PassportCheckResponse,
    new PassportCheckSoapClient,
    new PersonDocumentService
);

$passportCheckResponse = $passportCheckService->execute();

Imagine theres 5 more actions added to the service, now we need 5 more injections? Notice three of the dependancies passed in are just new instances.

Where am I going wrong here?

Many thanks.

Aucun commentaire:

Enregistrer un commentaire