generateFeature method
Generates a complete Clean Architecture feature structure.
name
- The name of the feature to generate (e.g., 'user_profile', 'authentication').
This method creates a complete feature following Clean Architecture principles:
- Data layer: datasources, models, repositories
- Domain layer: entities, repositories (abstracts), usecases
- Presentation layer: pages, controllers/blocs, bindings
The generated structure adapts to the configured state management pattern (GetX or BLoC) and includes appropriate dependencies and imports.
Example:
await fileGenerator.generateFeature('user_profile');
// Creates: lib/features/user_profile/...
Implementation
Future<void> generateFeature(String name) async {
final snakeName = templateGenerator.toSnakeCase(name);
final isBloc = templateGenerator.config.defaultStateManager == 'bloc';
// Create directory structure based on state manager
final dirs = [
'lib/features/$snakeName/data/datasources',
'lib/features/$snakeName/data/models',
'lib/features/$snakeName/data/repositories',
'lib/features/$snakeName/domain/entities',
'lib/features/$snakeName/domain/repositories',
'lib/features/$snakeName/domain/usecases',
'lib/features/$snakeName/presentation/pages',
'lib/features/$snakeName/presentation/bindings',
];
// Add state manager specific directories
if (isBloc) {
dirs.add('lib/features/$snakeName/presentation/bloc');
} else {
dirs.add('lib/features/$snakeName/presentation/controllers');
}
for (final dir in dirs) {
await ensureDirectoryExists(dir);
}
// Generate common files
final files = <String, String>{
'lib/features/$snakeName/domain/entities/${snakeName}_entity.dart':
templateGenerator.generateEntity(name),
'lib/features/$snakeName/data/models/${snakeName}_model.dart':
templateGenerator.generateModel(name),
'lib/features/$snakeName/domain/repositories/${snakeName}_repository.dart':
templateGenerator.generateRepositoryInterface(name),
'lib/features/$snakeName/data/repositories/${snakeName}_repository_impl.dart':
templateGenerator.generateRepositoryImplementation(name),
'lib/features/$snakeName/data/datasources/${snakeName}_remote_data_source.dart':
templateGenerator.generateDataSource(name),
'lib/features/$snakeName/domain/usecases/${snakeName}_usecase.dart':
templateGenerator.generateUseCase(name),
'lib/features/$snakeName/presentation/pages/${snakeName}_page.dart':
templateGenerator.generatePage(name),
'lib/features/$snakeName/presentation/bindings/${snakeName}_binding.dart':
templateGenerator.generateBinding(name),
};
// Add state manager specific files
if (isBloc) {
files['lib/features/$snakeName/presentation/bloc/${snakeName}_bloc.dart'] =
templateGenerator.generateController(name);
files['lib/features/$snakeName/presentation/bloc/${snakeName}_event.dart'] =
templateGenerator.generateBlocEvent(name);
files['lib/features/$snakeName/presentation/bloc/${snakeName}_state.dart'] =
templateGenerator.generateBlocState(name);
} else {
files['lib/features/$snakeName/presentation/controllers/${snakeName}_controller.dart'] =
templateGenerator.generateController(name);
}
for (final entry in files.entries) {
await writeFile(entry.key, entry.value);
}
print('✅ Generated feature "$name" with files:');
for (final filePath in files.keys) {
print(' - $filePath');
}
}