CodeBlanks Logo Icon CodeBlanks

Summary - Architecture

Combine clean, repository and DI to write an architecture skeleton.

Summary - Architecture

This group covered Dart architecture: clean architecture (layer separation), feature-based (feature-oriented organization), repository (data access abstraction), dependency injection, SOLID (design principles).

Core: dependencies flow inward; the domain layer depends on nothing. Repository hides the data source; DI provides interface-based dependencies. SOLID is the foundation of maintainable, testable code.

These patterns work together: clean architecture sets the frame, feature-based the organization, repository the data layer, DI the dependency management, SOLID the class design.

Practice Summary: entity + repository + container

Define an Order class with final String id; final int total; Order(this.id, this.total);. Define an abstract class OrderRepository with Order find(String id);. Define a class MockOrderRepo implements OrderRepository with @override Order find(String id) => Order(id, 250);. Define a class Container with final Map<String, dynamic> _items = {}; void register(String key, dynamic item) => _items[key] = item; T resolve<T>(String key) => _items[key] as T;. In main create final c = Container();; call c.register('repo', MockOrderRepo());; add final repo = c.resolve<OrderRepository>('repo');; final order = repo.find('ord-1'); and print('${order.id}: ${order.total}');.

Starter code

main.dart
void main() {
  // define Order entity, abstract OrderRepository and MockOrderRepo
  // define a Container class (register, resolve methods)
  // create a container; register repo; resolve; print order
}

Sample solution

main.dart
class Order {
  final String id;
  final int total;
  Order(this.id, this.total);
}

abstract class OrderRepository {
  Order find(String id);
}

class MockOrderRepo implements OrderRepository {
  @override
  Order find(String id) => Order(id, 250);
}

class Container {
  final Map<String, dynamic> _items = {};
  void register(String key, dynamic item) => _items[key] = item;
  T resolve<T>(String key) => _items[key] as T;
}

void main() {
  final c = Container();
  c.register('repo', MockOrderRepo());
  final repo = c.resolve<OrderRepository>('repo');
  final order = repo.find('ord-1');
  print('${order.id}: ${order.total}');
}

Expected output

ord-1: 250

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What do Repository + DI provide together?

  • Testable, swappable design Correct answer
  • Fewer lines of code
  • Faster UI
  • Automatic code generation

Explanation: Repository abstracts, DI injects; together they provide testability.

2 Match the architecture concepts

Term Meaning
Entity Domain model
Repository Contract
Container DI container
Feature Module

3 The Repository interface

Question
____ class OrderRepository { }
Answer
abstract class OrderRepository { }

Explanation: abstract class defines a contract.

All lessons in Expert