resolve 0.2.2

Resolve #

Managing dependencies with simple Widgets.

Features:

  • Inversion of control, you define how to instantiate objects from outside
  • Really integrated with the Flutter widget composability approach
  • Scoped resolution since Resolvers and Configurators can be overriden wherever in the tree
  • Generic widgets so you can use the configuration and instances you want

Examples #

Quickstart #

Provider

class Bootstrapper extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return Provider<String>(
            creator: (context) => "Hello world!",
            child: HomePage());
    }
}

class HomePage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final label = Resolver.of<String>(context);
        return Text(label);
    }
}

Resolver

enum Configuration {
  development,
  production,
}

class Bootstrapper extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return Configurator<Configuration>(
            configuration: Configuration.production,
            child: Resolver<String, Configuration>(
            creator: ((context,config) => config == Configuration.development ? "Debug now" : "Online"),
            child: HomePage());
    }
}

class HomePage extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final label = Resolver.of<String>(context);
        return Text(label);
    }
}

FAQ #

Can I use it with the BLoC pattern ?

Absolutely, I created it first for it, but wanted a more generic approach combined with dependency configuration. The solution is just an extended part of a typical bloc provider.

Don't forget to add a disposer for your blocs when registering them into the Resolver to close all exposed streams!

What if I have a pure Dart project ?

You can still use dioc which is a more traditionnal approach to inversion of control.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:resolve/resolve.dart';
import 'package:example/service.dart';

void main() => runApp(
    Bootstrapper(configuration: Configuration.production, child: MyApp()));

enum Configuration {
  development,
  production,
}

class Bootstrapper extends StatelessWidget {
  Bootstrapper({@required this.configuration, this.child});

  final Configuration configuration;

  final Widget child;

  static Color _createColor(BuildContext context, Configuration config) =>
      (config == Configuration.development ? Colors.red : Colors.blue);

  static CatFactService _createService(
          BuildContext context, Configuration config) =>
      (config == Configuration.development
          ? MockCatFactService()
          : OnlineCatFactService());

  @override
  Widget build(BuildContext context) {
    return Configurator<Configuration>(
        configuration: this.configuration,
        child: Resolver<Color, Configuration>(
            creator: _createColor,
            child: Resolver<CatFactService, Configuration>(
                creator: _createService, child: child)));
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Resolver Demo',
      theme: ThemeData(
        primarySwatch: Resolver.of<Color>(context),
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  HomePage({
    Key key,
  }) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Fact> facts = [];
  String status = "not loaded";

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future _load() async {
    final service = Resolver.of<CatFactService>(this.context);
    this.setState(() => this.status = "loading ....");
    try {
      final newFacts = await service.getRandom();
      this.setState(() {
        this.facts = newFacts;
        this.status = "loaded";
      });
    } catch (e) {
      this.setState(() => this.status = "error: " + e.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Resolver example | ' + Configurator.of<Configuration>(context).toString()),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            this.status,
          ),
          Expanded(
              child: ListView.builder(
            itemCount: this.facts.length,
            itemBuilder: (c, i) => Padding(
                padding: EdgeInsets.only(bottom: 40, left: 20, right: 20),
                child: Text(
                  this.facts[i].text,
                  style: Theme.of(context).textTheme.display1,
                )),
          ))
        ],
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  resolve: ^0.2.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:resolve/resolve.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
8
Health:
Code health derived from static analysis. [more]
99
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
9
Overall:
Weighted score of the above. [more]
35
Learn more about scoring.

We analyzed this package on Jul 2, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.9+1
  • Flutter: 1.17.3

Analysis suggestions

Package not compatible with SDK dart

because of import path [resolve]

Health suggestions

Fix lib/src/configurator.dart. (-0.50 points)

Analysis of lib/src/configurator.dart reported 1 hint:

line 32 col 17: 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Fix lib/src/resolver.dart. (-0.50 points)

Analysis of lib/src/resolver.dart reported 1 hint:

line 58 col 17: 'ancestorInheritedElementForWidgetOfExactType' is deprecated and shouldn't be used. Use getElementForInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Format lib/resolve.dart.

Run flutter format to format lib/resolve.dart.

Format lib/src/utils.dart.

Run flutter format to format lib/src/utils.dart.

Maintenance issues and suggestions

Provide a file named CHANGELOG.md. (-20 points)

Changelog entries help developers follow the progress of your package. See the example generated by stagehand.

Package is getting outdated. (-53.42 points)

The package was last published 80 weeks ago.

The package description is too short. (-18 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0-dev <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.0
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8
Dev dependencies
flutter_test
test ^1.3.3