Laravel Dependency Injection and Constructor Method with Example

Hello LaraDevs !

Dependency Injection is great way to clean your controller code and code Isolation. The word Dependency Injection sounds fancy that essentially means this: class dependencies are "injected" into the class via the constructor.. If you don't know what is dependency injection, don't worry, its just another PHP class which adds another layer to the controller/method.

To inject dependency we just use the __construct method and pass the newly created class as parameter. In Laravel its common convention to call these type of class as Repository . Its helps our application on Loose Coupling.

Why and When we need to create Repository?

Lets say inside our articleController 's store method, we have following lines of code.

 /**
     * Store a newly created resource in storage.
     *
     * @param  App\Http\Request\ArticleRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ArticleRequest $request)
    {
        try {
            if ($request->image) {
                //Get image name
                $imageName =  microtime() . "-" . $request->image->getClientOriginalName();
                // Save Image in Storage folder
                Storage::disk('public')->put($imageName, file_get_contents($request->image));
                // Create Article
                Article::create([
                    'title' => $request->title,
                    'image' => asset(Storage::url($imageName)),
                    'description' => $request->description,
                    'status' => $request->status,
                ]);
            } else {
                // In case of no image
                Article::create($request->all());
            }
			
            // Return Success Response
            return redirect()->back()-with([
                'message' => "Article Creatde Succesfully."
            ]);
        } catch (\Exception $e) {
            // Return Error Response
            return redirect()->back()-with([
                'message' => "Something Seems Not Good Today!"
            ]);
        }
    } 

In above method to store an article we have to perform different logics like checking if the request has image or not, if has create unique name and get content, store the image in public path.

The above method looks messed and imagine if we have to do more things like adding categories and sub categories, tags, store image in different table, the controller become more messed and hard to maintain.

The code will become tightly coupled and it becomes very difficult to test the code. To overcome this type of problems we can use dependency injection and shift all the complicated logics to the new class and inject to our controller. This will also increase code reusability and helps on code cleaning plush reduce maintenance time.

Creating A Repository

To create a repository we will create a separate directory inside our App directory and name it Repositories . You are free to create as many directories inside app in Laravel and all will load automatically due to PSR-4 autoloader. If not just run composer dump-autoload and it will definitely load.

For the articleController lets create a ArticleRepository inside App/Repositories and add the following code.

<?php


namespace App\Repositories;


use App\Models\Article;
use Illuminate\Support\Facades\Storage;

class ArticleRepository
{

    /**
     * Store new article
     *
     * @param  $request
     * @return message
     */
    public function createNewArticle($data)
    {
			try {
            if ($request->image) {
              $this->StoreArticleWithImage($data)
            } else {
                // In case of no image
                Article::create($request->all());
                return "Article created Successfully."
            }
            
          } catch (\Exception $e) {
            // Return Error Response
            return "Something Seems Not Good Today!"
      }
        
  public function StoreArticleWithImage($data)
  {
        //Get image name
         $imageName =  microtime() . "-" . $request->image-         			>getClientOriginalName();
      
             // Save Image in Storage folder
              Storage::disk('public')->put($imageName, file_get_contents($request->image));
      
                // Create Article
                Article::create([
                    'title' => $request->title,
                    'image' => asset(Storage::url($imageName)),
                    'description' => $request->description,
                    'status' => $request->status,
                ]);
      		return "Article created Successfully."
  }
} 

In above Class inside createNewArticle method we have shifted all the logics to store new article in our database. we have also refactored our code by creating another public function to store the article if it has image in our request.

Injecting the Dependency/Repository in the controller

Now its time to inject our new class or repository/dependency to the controller. For that we use the __cunstruct() method. So we have to update our ArticleController. Lets see following example.

use App\Repositories\ArticleRepository;



class ArticleController extends Controller
{
   
/**
    * The Article repository instance.
    *
    * @var articleRepository
    */
   protected $articleRepository;

   /**
    * Create a new controller instance.
    *
    * @param  ArticleRepository  $tasks
    * @return void
    */
   public function __construct(ArticleRepository $articleRepository)
   {
       $this->ArticleRepository = $articleRepository;
   }
   
   /**
    * Store a newly created resource in storage.
    *
    * @param  App\Http\Request\ArticleRequest  $request
    * @return \Illuminate\Http\Response
    */
   public function store(ArticleRequest $request)
   {
      $message = $this->ArticleRepository->createNewArticle($request->all());
       return redirect()->back()->with('message' => $message);
   }
} 

Did you just noticed that our controller looks more cleaner now. it reduced to just tow lines. Or we can say one line.

Summary

In above example I have explained just basic of the dependency injection, with a simplest example. We can do more things with dependency like refactor some code repetition in single method and call that method when needed.

Hope you get something useful in this article. If you have any questions you can drop in the comments. Thanks for reading.

Comments :