Automatically generate usecase classes from your repository class definition in Dart and Flutter

Overview

Repo Case

GitHub: SandroMaglione Twitter: SandroMaglione

Automatically generate usecase classes from your repository class definition in Dart and Flutter.

Check out the official guide on repo_case and Clean Architecture

Made by Sandro Maglione, check out his personal official website sandromaglione.com

Overview

  1. Import the package (as well as the repo_case_generator and build_runner)
  2. Create a repository class
  3. Annotate the class with @repoCase
  4. Run the build
  5. Complete!

Quick tutorial

Create your repository class definition in a new repository.dart file and annotate it with @repoCase:

@repoCase
abstract class UserRepository {
  String getString(int param);
}

Launch the build command to generate the usecase class:

flutter pub run build_runner build

The package will generate a usecase class for each method of the repository in a new repository.rc.dart file as follows:

class GetStringRepo {
  final UserRepository userRepository;

  const GetStringRepo({
    @required this.userRepository,
  });

  String call(GetStringRepoParams params) {
    return userRepository.getString(
      params.param,
    );
  }
}

class GetStringRepoParams {
  final int param;

  const GetStringRepoParams({
    @required this.param,
  });
}

You can now use the usecase class to access the repository:

/// Call repository with correct parameters
final String result = getStringRepo(
    GetStringRepoParams(
        param: 1,
    ),
);

Motivation

This package is inspired by the by the Flutter TDD Clean Architecture Course from Reso Coder.

Specifically, the goal of the package is to autogenerate usecase classes. The template for the usecase class is presented in the 2nd video of the course.

The usecase class aims to abstract the domain layer from the presentation layer. For each method of the repository class we should write a new usecase class, which is then called from the presentation layer to access the repository.

Repository-Usecases-Presentation diagram

The template of each usecase class as presented in the course is basically always the same. The only differences are the name of the method, the parameters, and its return type. Perfect usecase for code generation!

Import the package

Import the repo_case package as a normal dependencies and the repo_case_generator package as a dev_dependencies as well as the build_runner package (needed for code generation) in your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  repo_case: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter
    
  build_runner: any
  repo_case_generator: ^0.1.2

Clean Architecture

Entity

The entity class contains all the data exposed to the presentation layer, which comes from the data layer (database, local storage, etc.) and is accessed through the domain layer. The presentation layer will call the usecase class to access the entity to be displayed in the app.

We create a new domain folder and an entities folder inside it. We then create a entity class in a new entity.dart file inside the entities folder:

/// lib/domain/entities/entity.dart
class Entity {
  final String data;

  const Entity(this.data);
}

Model

The models are used to fetch and convert external raw data (json, xml, etc.) to dart objects. These classes extends the entities in order to be passed from the data layer to the presentation layer.

We create a new data folder and a models folder inside it. We then create a model class in a new model.dart file inside the models folder:

/// lib/data/models/model.dart
class Model extends Entity {
  const Model(String data) : super(data);
}

Repository

The repository contains the methods that will be called from the presentation layer to access the data from external sources. It defines all the usecases that can be accessed by the presentation layer. The repository will fetch the models from the data layer and return entities to the presentation layer.

We create a repository folder inside the domain folder. We then create a repository class in a new dart file. The file must contain an abstract class annotated with the @repoCase annotation:

/// lib/domain/repository/user_repository.dart
@repoCase
abstract class UserRepository {
  Entity getData(String param);
}

We can now run the build command to autogenerate the usecase classes:

flutter pub run build_runner build

This command will generate a new user_repository.rc.dart file in the same folder of the repository class (rc stays for 'repo_case'):

/// lib/domain/repository/user_repository.rc.dart
class GetDataRepo {
  final UserRepository userRepository;

  const GetDataRepo({
    @required this.userRepository,
  });

  Entity call(GetDataRepoParams params) {
    return userRepository.getData(
      params.param,
    );
  }
}

class GetDataRepoParams {
  final String param;

  const GetDataRepoParams({
    @required this.param,
  });
}

Repository concrete implementation

We must also define the concrete implementation of the repository class that will fetch the model from the data layer and return the respective entity.

We create a new repository folder inside the data folder. We then create a new file containing the concrete implementation of our repository:

class UserRepositoryImpl implements UserRepository {
  @override
  Entity getData(String param) {
    /// Get data from data sources (database, local storage, etc.)
    return Model(param);
  }
}

Access the entity from the presentation layer

We can now call the usecase class from the presentation layer to access the entities.

For example, we could have a bloc class that defines a method to fetch an entity to display in the app. Here below an example of how we would implement it:

class UserBloc {
  /// Usecase class generated by the repo_case package
  final GetDataRepo getDataRepo;

  const UserBloc(this.getDataRepo);

  Entity getDataFromRepository(String param) {
    return getDataRepo(
      /// Params class generated by the repo_case package
      GetDataRepoParams(
        param: param,
      ),
    );
  }
}

Injectable

The package is designed to work with the injectable package.

All the usecase classes have the -Repo suffix. You can therefore add the following rule to your build.yaml file to automatically add the usecase classes to the list of classes generated by the injectable package. Check out the example for more details:

targets:
  $default:
    builders:
      injectable_generator:injectable_builder:
        options:
          auto_register: true
          class_name_pattern: "Repo$"

Roadmap

I am always open for suggestions and ideas for possible improvements or fixes.

Feel free to open a Pull Request if you would like to contribute to the project.

If you would like to have a new feature implemented, just write a new issue.

Versioning

  • v0.1.2 - 20 November 2020
  • v0.1.1 - 20 November 2020
  • v0.1.0 - 15 November 2020

License

MIT License, see the LICENSE.md file for details.

You might also like...

A builder that generates an ArgsParser from a class

Parse command line arguments directly into an annotation class using the Dart Build System. Example Annotate a class with @CliOptions() from package:b

Oct 30, 2022

generate massive amounts of fake data in dart and flutter

generate massive amounts of fake data in Dart & Flutter Faker.dart is a dart port of the famous faker.js package for the web and NodeJS 🔨 Usage faker

Nov 28, 2022

Provides API to generate Dart source code

DartWriter DartWriter provides API to generate Dart source code. It can make your job easier while developing flutter/dart tools. You can also generat

Oct 24, 2022

Generate random data(string, integer, IPs etc...) using Dart.

Generate random data(string, integer, IPs etc...) using Dart.

Generate random data using Features API provides generation of: Integers in any range of numbers Strings with various characters and length Colors rep

Apr 17, 2022

A simple command-line application to generate simple folder and file structure for Flutter Applications

A simple command-line application to generate simple folder and file structure for Flutter Applications

Kanza_cli is a simple command line tool to generate folder and file structure for your Flutter apps. To use it, you should do the followings: 1. First

Dec 16, 2022

Parse cron string to schedule and generate previous or next schedule item

Parse cron string to schedule and generate previous or next schedule item

Apr 17, 2022

Flutter Cool Random User Generate 🔥🔥

Flutter Cool Random User Generate 🔥🔥

Flutter Cool Random User Generate 🔥🔥

Sep 10, 2022

Generate gherkin automated tests

Generate gherkin automated tests

flutter_gherkin_automated Generate gherkin automated tests Preliminary: integration tests performance vs. development Original flutter_gherkin BDD tes

Jul 7, 2022
Comments
Owner
Sandro Maglione
Coding since I was 12 💻 | Master in Computer Science and Engineering 👨‍🎓 | Open-Source developer 🎉 | Writing technical guides and tutorial articles ✍
Sandro Maglione
Provides simple conversion between Dart classes and Protobuf / Fixnum classes used in gRPC.

grpc_protobuf_convert Provides simple conversion between Dart classes and Protobuf / Fixnum classes used in gRPC. Using the library Add the repo to yo

null 2 Nov 1, 2022
A CLI tool to help generate dart classes from json returned from API

Json 2 Dart Command line utility Important note There is already a package called json2dart so this package will be called json2dartc ! This project w

Adib Mohsin 38 Oct 5, 2022
Contains utility functions and classes in the style of dart:collection to make working with collections easier

The collection package for Dart contains a number of separate libraries with utility functions and classes that makes working with collections easier.

Dart 273 Dec 27, 2022
Dart Code Generator for generating mapper classes

Smartstruct - Dart bean mappings - the easy nullsafe way! Code generator for generating type-safe mappers in dart, inspired by https://mapstruct.org/

Nils 28 Nov 29, 2022
A simple Flutter / Dart Utility class for converting complex objects to uri and query string

A simple Flutter / Dart Utility class for converting complex or nested objects to uri and query strings you can follow the the article on how this cla

Opata Joshua 5 Sep 7, 2022
AsyncCallQueue is a Dart class which provides a queuing mechanism to prevent concurrent access to asynchronous code.

async_call_queue AsyncCallQueue is a Dart class which provides a queuing mechanism to prevent concurrent access to asynchronous code. Getting Started

Ron Booth 2 Jan 18, 2022
Converts SVG icons to OTF font and generates Flutter-compatible class. Provides an API and a CLI tool.

Fontify The Fontify package provides an easy way to convert SVG icons to OpenType font and generate Flutter-compatible class that contains identifiers

Igor Kharakhordin 88 Oct 28, 2022
A flutter package with classes to help testing applications using the canvas

Canvas test helpers MockCanvas is a utility class for writing tests for canvas operations. It supports the same API as the regular Canvas class from d

Blue Fire 12 Jan 31, 2022
This is a simple class to package up and send requests to the Kroki.io web service.

Kroki.dart This is a simple class to package up and send requests to the Kroki.io web service. A live editor to editing diagrams that Kroki supports c

Tim Maffett 1 Jun 8, 2022
A generator to create config class from json files that support many environments

A generator to create config class from json files that support many environments. Motivation If you use a json file to config your applications, perp

Diego Cardenas 0 Oct 9, 2021