A sample flutter app using Injection, routing and simple authentication follows clean code and best practices
Flutter Clean Project
A sample flutter app using Injection, routing and simple authentication follows clean code and best practices
Features
- Cleaned flutter project
- Used linter with rules as errors
- Configured route generator
- Pass parameters / variables through routes
- Simple AuthService & configured Guard for routes
- Well structured flutter project contains Screens, Components, Services and so on..
Used Packages
dependenciesdev_dependencies
Getting Started
Project root folder
The project root folder is src. In order to take advantage of VS Code settings open src as your work folder.
Building
Auto generated files are committed into this repository. if you changed any part of codes which used auto generators you will have a compilation error. This can be
resolved by running the auto generation command to create the sources necessary again
to compile the app.
After checking out the branch simply run:
flutter pub run build_runner build --delete-conflicting-outputs
You can also use the watch command to constantly generate files on change:
flutter pub run build_runner watch --delete-conflicting-outputs
Dependency Injection
Dependency injection is done by using
Injectable package.
After you run the build_runner command a file named
setup.config.dart will get generated which holds all the injections.
Routing
Routing is done by using
AutoRoute package.
There is a service called router in /Services which using AutoRoute package to generate routes and paths in app.
After you run the build_runner command a file named
router.gr.dart will get generated which holds all the routes and classes used for routing.
also for showcasing how to pass parameters from paths to screens, see /home/message/message_screen_v.dart
State Management
Selected state management for this project is Cubit.
The Cubit is a subset of the famous implementation of BLoC Pattern: bloclibrary.dev, it abandons the concept of Events and simplifies the way of emitting states.
There are 3 parts for each component / screen to managing the states.
-
name_m.dart- Model: this file contains definition of models for state management. to reduce duplicate codes like
copyWith,isA[Class]and so on, I used Freezed package to auto generate needed classes and constructors for each state model.
- each model extends from BaseState class.
- Model: this file contains definition of models for state management. to reduce duplicate codes like
-
name_v.dart- View: this file contains the view for our component / screen which extends from BaseView class. the
BaseViewclass itself extends fromStatelessWidgetand has a getter to get the viewModel inside the view. it’s usinglocateService<T>()and Injectable DI.
- View: this file contains the view for our component / screen which extends from BaseView class. the
-
name_vm.dart- ViewModel: this file contains the viewModel for our component / screen which extends from BaseViewModel class (T is the state Model class). the
BaseViewModel<T>class itself extends fromcubit<T>.
- ViewModel: this file contains the viewModel for our component / screen which extends from BaseViewModel class (T is the state Model class). the
Screens
I defined 3 screens in this project.
- Home
- the root path of application.
- have a link to
messagescreen with passing a parameter to it. - using
AuthServiceto logout user. - showing
countercomponent in it.
- have a link to
- the root path of application.
- message
- a screen to demo how to get a parameter in our routing system.
- the input parameter is defined in view’s constructor [
String message]. - also in the routing service, I have to define the input parameter for this screen.
- the input parameter is defined in view’s constructor [
- a screen to demo how to get a parameter in our routing system.
- login
- login screen with a simple button and use
AuthServiceto do the fake login in application.- there is optional parameter called
redirectPathwhich used by router to navigate user back to where he/she been after successful login. - to guard selected routes and navigate user to this screen, I defined class
AuthenticatedUserin the routing service class.
- there is optional parameter called
- login screen with a simple button and use
there is a file in each folder with
folder_name.dartpattern name, which includes exports of files inside that folder. I use this pattern to minimize imports for other parts of application and classes. in usage we only need to importcomponents.dartorscreens.dartto use each folders implementations.
Components
Right now there is only one component in this project to demonstrate how to use components in screens.
- counter
- a simple counter component with cubit state management.
- I used this component inside the
Homescreen.
Images
Contact me
if you have any question or suggestion, please contact me :