mcquenji_core library
McQuenji's Core Module
This is the core module for all my flutter projects. It contains all the basic functionalities that I use in all my projects. It is a work in progress and I will keep updating it as I go along.
Usage
To use this module in your project, add the following to your pubspec.yaml
file:
dependencies:
mcquenji_core:
git:
url: https://github.com/mcquenji/mcquenji_core.git
Then run flutter pub get
to install the package.
After that, import the module in your app's main module this:
import 'package:mcquenji_core/mcquenji_core.dart';
class AppModule extends Module {
@override
List<Module> get imports => [CoreModule()];
}
Now you can use all services and utilities provided by the module in your app.
final networkService = Modular.get<NetworkService>();
networkService.get('https://api.example.com').then((response) {
print(response.body);
});
Logging
All enteties (i.e. services, datasources, repositories) have a logger that can be used to log messages. The logger is a Logger
instance from the logging
package. The logger is named after the entity's runtime type.
To process the logs you can either use the LogHandlerService
or create your own log handler.
void main() {
// Call this AFTER modular is initialized
final handler = Modular.get<LogHandlerService>();
Logger.root.onRecord.listen(handler);
}
## Services
Services are classes that complete the most low-level tasks in the app. They are the only classes that can interact with the outside world. All other classes should depend on services to get their work done.
### Defining a new service
To define a new service, create a new abstract class that extends the `Service` class.
```dart
abstract class MyService extends Service {
@override
String get name => 'MyService';
// Your service implementation here
}
After that, create a new class that extends the abstract class and implements the required methods.
class MyServiceImpl extends MyService {
@override
Future<void> init() async {
// Initialize your service here
}
// Implement other methods here
}
Finally, register the service in the module the service is used in. If the service is also used in other modules, export it.
class MyModule extends Module {
@override
List<Module> get imports => [McQuenjiCore()];
@override
void binds(i){
i.add<MyService>(MyServiceImpl.new);
}
@override
exportBinds(i) {
i.add<MyService>(MyServiceImpl.new);
}
}
Datasources
Datasources are classes that interact with the data layer of the app. They are responsible for fetching and storing data from and to the data layer.
Defining a new datasource
To define a new datasource, create a new abstract class that extends the Datasource
class.
abstract class MyDatasource extends Datasource {
@override
String get name => 'MyDatasource';
MyDatasource(MyService service);
// Your datasource implementation here
}
After that, the steps are the same as defining a new service.
Repositories
Repositories are classes that provide tailored methods for a specific UI screen or feature. They are also responsible for state management and as extend Cubit
.
Defining a new repository
To define a new repository, create a new class that extends the Repository
class.
class MyRepository<MyState> extends Repository<MyState> {
MyRepository(MyService service, MyDatasource datasource) : super(myIntialState);
// Your repository implementation here
}
Classes
-
AsyncValue<
T> - Represents a value that is asynchronously loaded.
- ConnectivityService
- Service for checking the connectivity of the device.
- CoreModule
- Core module of all McQuenji projects.
- Datasource
- Base class for all datasources.
-
HttpResponse<
T> - A response received from an HTTP request made by a NetworkService.
-
IGenericSerializer<
Deserialized, Serialized> - A versatile serializer interface for converting objects between different formats.
- ILoggable
- A class that provides logging functionality.
- InitialBuildTrigger
- Passed as trigger in Repository.build when called the first time.
- LogHandlerService
- A service that handles logging.
- NetworkService
- Base class for all network services.
-
Repository<
State> - Base class for all repositories.
- Service
- Base class for all services.
- Tick
- A tick emitted by the TickRepository.
- TickInterval
- An interval at which TickRepository should emit ticks.
- TickRepository
- A repository that emits ticks at a specified interval. The emitted ticks can be used to trigger periodic updates in the application.
- UpdateTrigger
- Passed as trigger in Repository.build when called in the Repository.updateInterval.
Extensions
-
AsyncRepoExt
on Repository<
AsyncValue< State> > - Utility extension on repositories with an asynchronous state.
- LogRecordX on LogRecord
- Formatting extension for log records.
- RepositoryInjectorExt on Injector
- Utility extension on Injector.
-
RepoWatchExt
on Repository<
AsyncValue< State> > - Extension for watching asynchronous repositories in asynchronous repositories.
- StringX on String
- String utilities.
Functions
-
cubitConfig<
T extends Cubit> () → BindConfig< T> - This function is to be used when binding a Cubit to a Module.
-
repositoryConfig<
R extends Repository> () → BindConfig< R> - This function is to be used when binding a Repository to a Module. Use RepositoryInjectorExt.addRepository instead of manually calling this function.
Typedefs
-
JSON
= Map<
String, dynamic> - Type alias for a JSON object.
- Ticks = TickRepository
- Type alias for TickRepository.
Exceptions / Errors
- OfflineException
- Exception thrown when the device is offline.
- WaitForDataException
- Thrown when RepoWatchExt.waitForData is called on a repository that does not have data yet.