Back to list
pretodev

manageproviderservice

by pretodev

0🍴 0📅 Jan 21, 2026

SKILL.md


name: ManageProviderService description: Guidelines for creating and maintaining service providers, which handle dependency injection in Flutter/Riverpod.

Service providers handle dependency injection for repositories, clients, and other services. They are the simplest type of provider, focused solely on wiring dependencies together.

When to Use Service Providers

Use a Service Provider when you need to:

  • Provide dependency injection for repositories
  • Wire up external clients or services
  • Create shared infrastructure components
  • Provide data layer elements to features

Provider Types Overview

TypePurposeNaming PatternExample
ServiceDependency injection for services*ProvidertrainingRepositoryProvider
QueryPre-customized data sources for UI*Query or *ProvidertrainingFromIdProvider
CommandUse cases with loading/success/error states*Command or class nameaddExerciseProvider

Location

Service providers have two possible locations based on scope:

Feature-Specific Services

Path: lib/features/<feature>/providers/providers.dart

Use this for services that belong to a specific feature module.

Shared Services

Path: lib/shared/provider.dart

Use this for services shared across multiple features.

⚠️ Important: Only service providers go in lib/shared/provider.dart. Never place commands or queries there.

lib/features/<feature>/
├── data/
│   ├── <entity>.dart
│   └── <repository>.dart
├── providers/
│   ├── providers.dart           # Service providers (all data elements)
│   ├── <n>_query.dart           # Query providers
│   └── <action>_command.dart    # Command providers
└── ui/
    └── *.dart

lib/shared/
├── provider.dart                # Shared service providers ONLY
└── providers/
    └── command_provider_base_mixin.dart

Structure

Service providers are simple functions that wire dependencies:

// lib/features/trainning/providers/providers.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../data/firestore/firestore_trainning_document.dart';
import '../data/training_repository.dart';

part 'providers.g.dart';

@riverpod
TrainingRepository trainingRepository(Ref ref) {
  return TrainingRepository(
    trainingDocument: FirestoreTrainningDocument(),
  );
}

Naming Conventions

ElementConventionExample
File nameproviders.dart (feature) or provider.dart (shared)providers.dart
Function nameNoun describing the servicetrainingRepository
Provider nameGenerated with Provider suffixtrainingRepositoryProvider

Best Practices

PracticeDescription
Keep providers simpleFocus only on wiring dependencies
Use ref.read()Access other providers when needed
Avoid business logicServices wire, they don't implement logic
One file per featureproviders.dart provides all data elements of a feature
Shared services only in sharedlib/shared/provider.dart for cross-feature services

Examples

Feature Service Provider

// lib/features/auth/providers/providers.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../data/auth_repository.dart';
import '../data/firebase/firebase_auth_client.dart';

part 'providers.g.dart';

@riverpod
AuthRepository authRepository(Ref ref) {
  return AuthRepository(
    authClient: FirebaseAuthClient(),
  );
}

Service with Dependencies

// lib/features/notifications/providers/providers.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../data/notification_repository.dart';
import '../data/firebase/firebase_messaging_client.dart';
import '../../auth/providers/providers.dart';

part 'providers.g.dart';

@riverpod
NotificationRepository notificationRepository(Ref ref) {
  final authRepo = ref.read(authRepositoryProvider);

  return NotificationRepository(
    messagingClient: FirebaseMessagingClient(),
    authRepository: authRepo,
  );
}

Shared Service Provider

// lib/shared/provider.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';

import 'data/analytics_client.dart';
import 'data/crash_reporter.dart';

part 'provider.g.dart';

@riverpod
AnalyticsClient analyticsClient(Ref ref) {
  return AnalyticsClient();
}

@riverpod
CrashReporter crashReporter(Ref ref) {
  return CrashReporter();
}

Maintenance and Modification

When modifying existing service providers:

  1. Dependency Updates: If a service's constructor changes (e.g., new dependency), update the provider to supply it using ref.read() if it comes from another provider.
  2. Scope Management: If a service needs to be promoted from feature-specific to shared, move it to lib/shared/provider.dart and update imports.
  3. Cleanup: If a service is no longer used, remove the provider to keep the dependency graph clean.

Anti-Patterns to Avoid

❌ DON'T: Business Logic in Service Provider

// BAD: Business logic doesn't belong here
@riverpod
TrainingRepository trainingRepository(Ref ref) {
  final repo = TrainingRepository(
    trainingDocument: FirestoreTrainningDocument(),
  );

  // BAD: Don't add business logic
  if (someCondition) {
    repo.enableCaching();
  }

  return repo;
}

❌ DON'T: Commands in Shared Provider File

// lib/shared/provider.dart

// BAD: Commands should NOT be in shared provider file
@riverpod
class SomeGlobalCommand extends _$SomeGlobalCommand {
  // This belongs in a feature's providers folder
}

❌ DON'T: Queries in Shared Provider File

// lib/shared/provider.dart

// BAD: Queries should NOT be in shared provider file
@riverpod
Stream<User> currentUser(Ref ref) {
  // This belongs in a feature's providers folder
}

❌ DON'T: Complex Initialization Logic

// BAD: Too much logic for a service provider
@riverpod
Future<DatabaseClient> databaseClient(Ref ref) async {
  final client = DatabaseClient();

  // BAD: Complex initialization belongs elsewhere
  await client.connect();
  await client.runMigrations();
  await client.seedData();

  return client;
}

Code Smells

SmellProblemSolution
Business logic in service providerBreaks separation of concernsKeep services as pure dependency wiring
Commands/Queries in shared providerWrong locationMove to feature providers folder
Complex initializationService providers should be simpleUse a dedicated initializer or command
Using ref.watch()Unnecessary reactivityUse ref.read() in service providers

Code Generation

Always include the part directive and run code generation after changes:

import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'providers.g.dart';
dart run build_runner build -d

Note: The -d flag is short for --delete-conflicting-outputs.

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon