• Introduction To Dependency Injection

    Dependency Injection is a technique for resolving object dependencies during class initialization. It allows the creation of dependent objects outside of a class.

    This technique allows us to write clean code where we can program against interfaces rather than concrete class types. It also enables to write testable codes.

                                                      

    For example, in the code below, class A requires an object of type B in it’s constructor.

    class A {
      B b;
      A(B b) {
      }
    }
    
    abstract class B {
      doSomething();
    }
    
    class C implements B {
      doSomething() {
        ...
      }
    
     class D implements B {
       doSomething() {
        ...
       }
     }
    }

    The class B is an abstract class which acts as an interface. Class C could be it’s real implementation and D be it’s implementation for testing purpose.

    Depending upon whether we are running unit tests or running applications, class A’s constructor should receive a different instance of C or D. If the app is under test mode, you want to pass an object of type D in the A’s constructor. Otherwise, you want to pass an object of type C.

    A dependency injection technique allows to resolve such dependencies in an application during runtime.

    Dependency Injection In Flutter

    The steps to make use of the dependency manager in our Flutter app is going to be like this:

    • Create a dependency manager.
    • Add all the dependencies for the application in this manager.
    • Initialize the dependency manager when the application starts.
    • Use Inherited Widget to keep this manager in app’s state.
    • Get access to the dependency manager object via the app’s state.
    • Resolve dependencies during runtime via the injector object.

    For the purpose of this post, we will make use of a dependency injection plugin called “flutter_simple_dependency_injection

    Setup Dependency Manager

    Once you have added the package into your Flutter application, create a base class for dependency manager.

    import 'package:flutter_simple_dependency_injection/injector.dart';
    
    abstract class DependencyManagerBase {
      Injector injector;
    }

    We are making this class abstract in order to be able to create separate types of dependency manager based on test, development or production environments.

    Now, add a concrete implementation for this manager.

    class DependencyManager implements DependencyManagerBase {
    
      @override
      Injector injector;
    
      DependencyManager() {
        injector = Injector.getInjector();
        // Add your dependencies here
        injector.map<B>((i) => C());
      }  
    }

    We have initialized Injector in the constructor of the DependencyManager. The Injector object holds the list of all dependencies in your application.

    Now we need to make use of the dependency manager. For this purpose, we will use the Inherited Widget.

    Using Inherited Widget For Dependency Injection

    If you are completely new to Inherited Widget, you should check out  first.

    class AppStateProvider extends InheritedWidget {
      final AppState state;
      final DependencyManagerBase diBase;
    
      AppStateProvider(this.diBase, {Key key, Widget child})
          : state = new AppState(diBase),
            super(key: key, child: child){
              state.init();
            }
    
      @override
      bool updateShouldNotify(_) => false;
    
      static AppState of(BuildContext context) {
        return (context.inheritFromWidgetOfExactType(AppStateProvider)
                as AppStateProvider)
            .state;
      }
    }

    Here the AppStateProvider class is an InheritedWidget which manages the app state. The dependency manager is passed onto the AppState class.

    Once you the InheritedWidget setup, you can initialize the dependency manager like this:

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return AppStateProvider(
          DependencyManager(),//initialize the dependency manager
          child: MyHomePage(),
        );
      }
    }

    This allows us to get the AppState anywhere in the application by calling the static method “of“.

    final appState = AppStateProvider.of(context);

    Finally, you can access the injector object from anywhere in the application via the AppState object.

    var diManager = widget.appState.diBase;
    var a = A(diManager.injector.get<B>());
0 Years in
Operation
0 Loyal
Clients
0 Successful
Projects

Words from our clients

 

Tell Us About Your Project

We’ve done lot’s of work, Let’s Check some from here