MultiProviderの定義場所

「main.dart が provider だらけでゴチャゴチャ問題」代表的な解決パターン
1. Provider の定義を別ファイルに切り出す
もっともシンプルなやり方です。
・before(よくある main.dart)
main.dart
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AuthViewModel()),
ChangeNotifierProvider(create: (_) => UserViewModel()),
ChangeNotifierProvider(create: (_) => SettingsViewModel()),
ChangeNotifierProvider(create: (_) => ProductViewModel()),
// ...どんどん増える...
],
child: const MyApp(),
),
);
}
・after(providers.dart にまとめる)
providers.dart
// providers.dart
import 'package:provider/provider.dart';
import 'viewmodels/auth_view_model.dart';
import 'viewmodels/user_view_model.dart';
import 'viewmodels/settings_view_model.dart';
import 'viewmodels/product_view_model.dart';
final globalProviders = [
ChangeNotifierProvider(create: (_) => AuthViewModel()),
ChangeNotifierProvider(create: (_) => UserViewModel()),
ChangeNotifierProvider(create: (_) => SettingsViewModel()),
ChangeNotifierProvider(create: (_) => ProductViewModel()),
];
main.dart
// main.dart
import 'providers.dart';
void main() {
runApp(
MultiProvider(
providers: globalProviders,
child: const MyApp(),
),
);
}
2. AppProviders というラッパー Widget を作る
Widget として包むパターンも整理しやすく有効です。
app_providers.dart
// app_providers.dart
class AppProviders extends StatelessWidget {
final Widget child;
const AppProviders({super.key, required this.child});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => AuthViewModel()),
ChangeNotifierProvider(create: (_) => UserViewModel()),
],
child: child,
);
}
}
main.dart
// main.dart
void main() {
runApp(
AppProviders(
child: const MyApp(),
),
);
}
3. 必要なものだけ root に置く(機能ごとに分散)
役割ごとに Provider を分散させることで、main.dart の肥大化を防げます。
user_page.dart
class UserPage extends StatelessWidget {
const UserPage({super.key});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserViewModel()),
ChangeNotifierProvider(create: (_) => UserDetailViewModel()),
],
child: const UserPageBody(),
);
}
}
4. DI コンテナ(get_it 等)と組み合わせる
大規模プロジェクトでは DI コンテナを併用することで責務分離が進みます。
example.dart
ChangeNotifierProvider(
create: (_) => getIt(),
);
まとめ
- ・providers.dart や AppProviders で定義を分離
- ・本当に必要なものだけ root に置く
- ・画面単位の Provider は画面側に配置
