entidade 1.0.4
entidade: ^1.0.4 copied to clipboard
Code generators that augment classes that are meant to be used as business entities
This package includes code generators that augment classes that are meant to be used as business entities:
- Business rules validation
- copyWith method
- equivalence (== / hashCode)
- Builder class
Getting Started #
Validations #
Start by adding the @validatableannotation to the class for which you want validation code to be generated:
/// ensure the library has the part statement.
part 'recipe.data.dart';
@validatable
class Recipe {
final String title;
const Recipe({required this.title});
}
This will generate a Validator class that will contain a validation method for each of the properties of the class. By default each validation method will return null, as examplified:
/// This is an example of a generated validator class.
class RecipeValidator implements Validator {
const RecipeValidator();
ValidationError? validateTitle(String value) {
return null;
}
@override
ErrorList validate(covariant Recipe entity) {
var errors = <ValidationError>[];
ValidationError? error;
if ((error = validateTitle(entity.title)) != null) {
errors.add(error!);
}
return ErrorList(errors);
}
@override
void validateThrowing(covariant Recipe entity) {
var errors = validate(entity);
if (errors.validationErrors.isNotEmpty) throw errors;
}
Annotate each field with a rule that you want to apply to that field:
/// ensure the library has the part statement.
part 'ingredient.data.dart';
@validatable
class Ingredient {
@StringLength(minLength: 10)
final String description;
@StringLength(maxLength: 10)
final String? notes;
@StringLength(minLength: 2)
final String? tag;
@DoubleRange(minValue: 10, maxValue: 20)
final double quantity;
@Range(minValue: 10)
final Decimal precision;
@Range(minValue: 10, maxValue: 20)
final int intQuantity;
@Range(minValue: 10, maxValue: 20)
final int? nintQuantity;
@Range(minValue: 10, maxValue: 20)
@required
final int? rInt;
Ingredient({
required this.description,
required this.quantity,
required this.precision,
required this.intQuantity,
this.notes,
this.tag,
this.nintQuantity,
this.rInt,
});
}
Builder #
Add a @builder annotation:
/// ensure the library has the part statement.
part 'recipe.data.dart';
@builder
class Recipe {
final String title;
final String? description;
Recipe({
required this.title,
this.description,
});
}
This will generate a non-immutable builder class:
class RecipeBuilder implements Builder<Recipe> {
String title;
String? description;
RecipeBuilder({
required this.title,
this.description,
});
factory RecipeBuilder.fromRecipe(Recipe entity) {
return RecipeBuilder(
title: entity.title,
description: entity.description,
);
}
@override
Recipe build() {
var entity = Recipe(
title: title,
description: description,
);
RecipeValidator().validateThrowing(entity);
return entity;
}
}
copyWith and equivalence #
Add a @builder annotation:
/// ensure the library has the part statement.
part 'recipe.data.dart';
@data
class Recipe with _$Recipe {
final String title;
final String? description;
Recipe({
required this.title,
this.description,
});
}
This will generate a mixin that adds the copyWith method and the == and hashCode operators:
// **************************************************************************
// DataGenerator
// **************************************************************************
mixin _$Recipe {
String get title;
String? get description;
Recipe copyWith({
String? title,
CopyValue<String>? description,
}) {
return Recipe(
title: title ?? this.title,
description: description == null ? this.description : description.value,
);
}
@override
int get hashCode => Object.hash(
runtimeType,
title,
description,
);
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is Recipe &&
(identical(other.title, title) || other.title == title) &&
(identical(other.description, description) ||
other.description == description));
}
}
Context #
This package is part of a set of loosely integrated packages that constitute the Dartaculous Framework.