Service class

Service annotation for service layer components

This annotation marks a class as a service component. It's a specialization of @Component for the service layer.

Example Usage:

@Service()
class UserService {
  final UserRepository userRepository;
  final EmailService emailService;
  
  UserService(this.userRepository, this.emailService);
  
  Future<List<User>> findAll() async {
    return userRepository.findAll();
  }
  
  Future<User> findById(String id) async {
    final user = await userRepository.findById(id);
    if (user == null) {
      throw NotFoundException('User not found: $id');
    }
    return user;
  }
  
  @Transactional()
  Future<User> create(CreateUserRequest request) async {
    final user = User(
      id: generateId(),
      name: request.name,
      email: request.email,
      createdAt: DateTime.now(),
    );
    
    final savedUser = await userRepository.save(user);
    await emailService.sendWelcomeEmail(savedUser.email);
    
    return savedUser;
  }
  
  @Transactional()
  Future<User> update(String id, UpdateUserRequest request) async {
    final existingUser = await findById(id);
    
    final updatedUser = existingUser.copyWith(
      name: request.name,
      email: request.email,
      updatedAt: DateTime.now(),
    );
    
    return userRepository.save(updatedUser);
  }
  
  @Transactional()
  Future<void> delete(String id) async {
    final user = await findById(id);
    await userRepository.delete(user.id);
    await emailService.sendGoodbyeEmail(user.email);
  }
}

Marks a class as a Service Component within the dependency injection (DI) container.

The @Service annotation designates a class as a singleton, typically containing business logic, application use cases, or domain services. These classes are automatically detected, instantiated once, and injected wherever required.

It is semantically equivalent to @Component, but helps communicate the role of the class more explicitly (in the spirit of Domain-Driven Design).


🧩 Purpose:

  • Declare stateless, reusable business logic components
  • Promote separation of concerns between services, repositories, and controllers
  • Automatically register the service in the DI container

πŸ§ͺ Example:

@Service()
class UserService {
  final UserRepository _repo;

  UserService(this._repo);

  User? findById(String id) => _repo.findById(id);
}

The above service can now be injected:

class UserController {
  final UserService _userService;

  UserController(this._userService);
}

πŸ“¦ Typical Use Cases:

Type Role
UserService Business logic for user management
PaymentProcessorService Coordinates payment workflows
AuthService Authentication/authorization utilities

🧠 Characteristics:

  • Singleton Scope: A single instance is shared across the application.
  • Dependency-Aware: Can depend on other components like repositories, configurations, etc.
  • No side effects in constructor: Avoid non-trivial logic in the constructor.

πŸ”§ Usage Notes:

  • You can inject this class into other services, controllers, or components.
  • Use @Service() when your class contains core business logic and requires clear separation from lower-level infrastructure (like @Repository()).

🎯 Target:

This annotation can only be applied to class declarations:

@Service()
class EmailSender {
  void send(String email) => print('Sending to $email');
}

  • @Component – Generic DI component base
  • @Repository – Specializes in persistence/data access
  • @Configuration – Declares pod-producing configuration classes
  • @Controller – (Optional) Marks HTTP/web-facing logic

βœ… Best Practices:

  • Keep @Service classes stateless or minimally stateful
  • Inject required dependencies through constructor
  • Avoid tight coupling with frameworks for better testability

πŸ’‘ Tip:

If you're building your own DI container, treat @Service() as a specialization of @Component() with singleton semantics.


Annotations
  • @Component()
  • @Target.new({TargetKind.classType})

Constructors

Service([String? value])
Service annotation for service layer components
const

Properties

annotationType β†’ Type
Returns the annotation _type of this annotation.
no setter
hashCode β†’ int
The hash code for this object.
no setterinherited
runtimeType β†’ Type
A representation of the runtime type of the object.
no setterinherited
value β†’ String?
Optional service name
final

Methods

equalizedProperties() β†’ List<Object?>
Mixin-style contract for value-based equality, hashCode, and toString.
equals(Object other) β†’ bool
Checks whether the given object is logically equivalent to this annotation.
inherited
noSuchMethod(Invocation invocation) β†’ dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() β†’ String
Returns a string representation of this annotation.

Operators

operator ==(Object other) β†’ bool
The equality operator.
inherited