BloC architecture – BloC is short form for Business Logic Component. As it name suggest, we will use it for separating business logic from presentation logic.created by Felix Angelov and was introduced at Google I/O in 2019. Hence Bloc is not architecture itself, we still need to organize our data according to DDD, MVVM or other.
We will not discuss Pros and Cons here, We will move straight to its implementation in our flutter app.
BloC architecture components
- Event And Actions are input that appears when user interacts with app, like button click or scroll
- State is reaction to these event, it changes according to event
- A Bloc is responsible for business logic, It processes event and convert it into state
- Stream is asynchronous flow of data that UI and Bloc reacts.
Add Bloc architecture to app
We will go step by step to implement architecture :
- Add Dependency
dependencies:
flutter_bloc: ^7.0.0
2. Create Repository
├── android
├── ios
├── lib
├── packages
│ └── authentication_repository
└── test
We need to create pubspec.yaml for our new repository
name: authentication_repository
description: Dart package which manages the authentication domain.
publish_to: none
environment:
sdk: ">=2.12.0-0 <3.0.0"
Now create AuthenticationRepository class file and enum for AuthenticationStatus in lib/src/ in our newly created package
enum AuthenticationStatus{
unknown, authenticated, unauthenticated
}
import 'dart:async'; import 'package:authentication_repository/src/AuthenticationStatus.dart'; class AuthenticationRepository{ final _controller = StreamController<AuthenticationStatus>(); Stream<AuthenticationStatus> get status async* { await Future<void>.delayed(const Duration(seconds: 1)); yield AuthenticationStatus.unauthenticated; yield* _controller.stream; } Future<void> login() async{ await Future<void>.delayed(Duration(seconds: 1), (){ _controller.add(AuthenticationStatus.authenticated); }); } Future<void> logout() async{ await Future<void>.delayed(Duration(seconds: 1), (){ _controller.add(AuthenticationStatus.unauthenticated); }); } void dispose(){ _controller.close(); } }
Next we need to create authentication_repository.dart file which contains public exports
library authentication_repository;
export 'src/AuthenticationRepository.dart';
export 'src/AuthenticationStatus.dart';
We also need UserRepository to display details according to user
├── android
├── ios
├── lib
├── packages
│ ├── authentication_repository
│ └── user_repository
└── test
pubspec.yaml for user_repository
name: user_repository
description: Dart package which manages the user domain.
publish_to: none
environment:
sdk: ">=2.12.0-0 <3.0.0"
dependencies:
equatable: ^2.0.0
user model class – we have used Equatable to compare User model (create in lib/src/model)
import 'package:equatable/equatable.dart';
class User extends Equatable {
const User(this.id);
final String id;
@override
List<Object> get props => [id];
static const empty = User('-');
}
now we need to create models.dart file in lib/src/model with below content
export 'user.dart';
Now UserRepository with singe method getUser for simplicity, you need to add more as your requirements.
import 'dart:async';
import 'models/models.dart';
class UserRepository {
User? _user;
Future<User?> getUser() async {
if (_user != null) return _user;
return Future.delayed(
const Duration(milliseconds: 300),
() => _user = User("#GeneratedUserId"),
);
}
}
now we only need user_repository.dart in lib folder to export our package.
library user_repository;
export 'src/models/models.dart';
export 'src/user_repository.dart';
Add Repository dependency
add following paths in your main pubspec.yaml file under dependencies, be careful about spacing. yaml file is very strict about it. it uses 2 space rule.
authentication_repository:
path: packages/authentication_repository
user_repository:
path: packages/user_repository
Don’t forgot to pub get after editing yaml file. Stay tuned with us for part2 of How to implement Bloc architecture in flutter app, Please always use latest version of library whenever you import dependency.
Share this content: