flutter_modules_generator
A CLI tool designed to streamline and automate the generation of module structures for Flutter projects. This tool creates organized folder hierarchies and template files, including controllers, bindings, business logic, data models, services, and views. Adhering to the SOLID Principles, it simplifies project setup and enforces a consistent code structure.
CLI Usage
Installation
dart pub global activate flutter_modules_generator
Running the Generator
dart pub global run flutter_modules_generator <module_name> <usecases> <services>
Example
dart pub global run flutter_modules_generator user "create,read,update,delete" "auth,logger"
Updated Flutter project's pubspec.yaml:
dependencies:
flutter:
sdk: flutter
get: ^5.0.0-release-candidate-9.2.1
dio: ^5.7.0
Generated Structure Example
- user/
- controller/
- user_controller.dart
- bindings/
- user_binding.dart
- usecases/
- create.dart
- read.dart
- update.dart
- delete.dart
- data/
- api/
- user_api.dart
- json/
- models/
- services/
- auth_service.dart
- logger_service.dart
- views/
- viewmodels/
- widgets/
- user_view.dart
Prerequisite File
api_base.dart
import 'package:dio/dio.dart';
abstract class IBaseApi {
Dio dioApi();
}
Example Files Generated by the Tool
Controller Layer
Manages state using GetX.
user_controller.dart
import 'package:get/get.dart';
class UserController extends GetxController {}
user_binding.dart
import 'package:get/get.dart';
class UserBinding implements Binding {
@override
List<Bind> dependencies() {
return [
Bind.lazyPut(() => UserController()),
];
}
}
Use Cases
Encapsulate business logic.
create.dart
extension Create on UserController {}
abstract class ICreateData<T> {
Future<T> consume();
}
class CreateData implements ICreateData {
@override
Future consume() async {}
}
delete.dart
extension Delete on UserController {}
abstract class IDeleteData<T> {
Future<T> consume();
}
class DeleteData implements IDeleteData {
@override
Future consume() async {}
}
read.dart
extension Read on UserController {}
abstract class IReadData<T> {
Future<T> consume();
}
class ReadData implements IReadData {
@override
Future consume() async {}
}
update.dart
extension Update on UserController {}
abstract class IUpdateData<T> {
Future<T> consume();
}
class UpdateData implements IUpdateData {
@override
Future consume() async {}
}
Data Layer
user_api.dart
import 'package:dio/dio.dart';
class UserApi implements IBaseApi {
static final UserApi _instance = UserApi._internal();
factory UserApi() => _instance;
UserApi._internal();
final Dio _dio = Dio(
BaseOptions(
baseUrl: 'http://api.example.com/v1',
connectTimeout: Duration(seconds: 30),
receiveTimeout: Duration(seconds: 30),
),
)..interceptors.addAll([]);
@override
Dio dioApi() => _dio;
}
auth_service.dart
import 'package:dio/dio.dart';
import 'api_base.dart';
abstract class IAuthData<T> {
Future<T> consume();
}
class AuthService<T> implements IAuthData {
final IBaseApi api;
AuthService({required this.api});
@override
Future<T> consume() async {
try {
// Add your logic here
} on DioException catch (e) {
throw Exception(e.toString());
} catch (e) {
throw Exception(e.toString());
}
}
}
logger_service.dart
import 'package:dio/dio.dart';
import 'api_base.dart';
abstract class ILoggerData<T> {
Future<T> consume();
}
class LoggerService<T> implements ILoggerData {
final IBaseApi api;
LoggerService({required this.api});
@override
Future<T> consume() async {
try {
// Add your logic here
} on DioException catch (e) {
throw Exception(e.toString());
} catch (e) {
throw Exception(e.toString());
}
}
}
View Layer
user_view.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class UserView extends GetView<UserController> {
const UserView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('User View'),
),
body: Center(
child: const Text('Welcome to User View'),
),
);
}
}