get_it 1.0.2

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 94

get_it

IMPORTANT: You have to use Dart2 to use this component

You can find here a detailed blog post on how to use GetIt

This is a simple Service Locator for Dart and Flutter projects highly inspired by Splat.

If you are not familiar with the concept of Service Locators, its a way to decouple the interface (abstract base class) from a concrete implementation and at the same time allows to access the concrete implementation from everywhere in your App over the interface. I can only highly recommend to read this classic article by from Martin Fowler Inversion of Control Containers and the Dependency Injection pattern

Accessing an object from anywhere in an App especially can be done by other ways too but:

  • If you use a Singleton you cannot easily switch the implementation to another like a mock version for unit tests
  • IoC containers for Dependency Injections offer a similar functionality but with the cost of slow start-up time and less readability because you don't know where the magically injected object come from. As most IoC libs rely on reflection they cannot be used with Flutter.

Typical usage:

  • Accessing service objects like REST API clients, databases so that they easily can be mocked.
  • Accessing View/AppModels from Flutter Views
  • Because interface and implementations are decoupled you could also register Flutter Views with different implementations and decide at start-up which one you want to use e.g. depending on screen resolutions

Extremely important if you use GetIt: ALWAYS use the same style to import your project files either as relative paths OR as package which I recommend. DON'T mix them because currently Dart treats types imported in different ways as two different types although both reference the same file.

Getting Started

Most Service Locator libraries are implemented either as Singletons or static classes depending on the features of the programming languages so that they can be easily accessed. As Dart supports global (or euphemistic ambient) variables I decided after some discussions with Simon Lightfoot and Brian Egan to use just a simple class (so that you can if you really need even create more than one Locator although I would not advise to do that in most cases).

So to use GetIt you only have to declare an instance of it in your App, typically as global variable.

GetIt getIt = new GetIt();

You can use any name you want which makes Brian happy ;-)

Before you can access your objects you have to register them within GetIt typically direct in your start-up code.

getIt.registerSingleton<AppModel>(new AppModelImplementation());
getIt.registerLazySingleton<RESTAPI>(() =>new RestAPIImplementation());

AppModel and RESTAPI are both abstract base classes in this example

To access the registered objects call get<Type>() on your GetItinstance

var myAppModel = getIt.get<AppModel>();

Alternatively as GetIt is a callable class depending on the name you choose for your GetItinstance you can use the shorter version:

var myAppModel = getIt<AppModel>();

Different ways of registration

Although I always would recommend using an abstract base class as registration type so that you can vary the implementations you don't have to do this. You can also register concrete types.

GetIt offers different ways how objects are registered that effect the lifetime of this objects.

Factory

void registerFactory<T>(FactoryFunc<T> func)

You have to pass a factory function func that returns an instance of an implementation of T. Each time you call get<T>() you will get a new instance returned.

Singleton && LazySingleton

void registerSingleton<T>(T instance) 

You have to pass an instance of T or a derived class of T that you will always get returned on a call to get<T>().

As creating this instance can be time consuming at app start-up you can shift the creation to the time the object is the first time requested with:

void registerLazySingleton<T>(FactoryFunc<T> func)

You have to pass a factory function func that returns an instance of an implementation of T. Only the first time you call get<T>() this factory function will be called to create a new instance. After that you will always get the same instance returned.

Overwriting registrations

If you try to register a type more than once you will get an assertion in debug mode because normally this is not needed and not advised and probably a bug. If you really have to overwrite a registration, then you can by setting the property `allowReassignment==true`` .

Resetting GetIt

  /// Clears all registered types. Handy when writing unit tests
  void reset()

Acknowledgements

Many thanks to the insightful discussions on the API with Brian Egan and Simon Lightfoot

[1.0.0] - 22.05.2018

  • Initial release

[1.0.1] - 20.06.2018

  • Added reset()method

[1.0.2] - 22.06.2018

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:get_it_example/app_model.dart';


// This is our global ServiceLocator
GetIt getIt = new GetIt();

void main() {

  getIt.registerSingleton<AppModel>(new AppModelImplementation());

  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  initState()
  {
    // Access the instance of the registered AppModel
    getIt<AppModel>().addListener(update); 
    // Alternative
    // getIt.get<AppModel>().addListener(update); 
    
    super.initState();
  }

  @override
  void dispose() {
      getIt<AppModel>().removeListener(update); 
      super.dispose();
    }

  update()=> setState(()=>{});

  @override
  Widget build(BuildContext context) {

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '${getIt<AppModel>().counter}',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: getIt<AppModel>().incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  get_it: ^1.0.2

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:get_it/get_it.dart';
  
Version Uploaded Documentation Archive
1.0.2 Jun 22, 2018 Go to the documentation of get_it 1.0.2 Download get_it 1.0.2 archive
1.0.1+1 Jun 4, 2018 Go to the documentation of get_it 1.0.1+1 Download get_it 1.0.1+1 archive
1.0.1 Jun 4, 2018 Go to the documentation of get_it 1.0.1 Download get_it 1.0.1 archive
1.0.0+2 May 22, 2018 Go to the documentation of get_it 1.0.0+2 Download get_it 1.0.0+2 archive
1.0.0+1 May 22, 2018 Go to the documentation of get_it 1.0.0+1 Download get_it 1.0.0+1 archive
1.0.0 May 22, 2018 Go to the documentation of get_it 1.0.0 Download get_it 1.0.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
88
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
94
Learn more about scoring.

We analyzed this package on Oct 10, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.4

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:get_it/get_it.dart.

Health suggestions

Format lib/get_it.dart.

Run dartfmt to format lib/get_it.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev<3.0.0
Dev dependencies
test any