Flutter服务提供插件flutter_service_provider的使用
Flutter服务提供插件flutter_service_provider的使用
flutter_service_provider
是一个用于在Flutter应用中管理依赖注入(Dependency Injection, DI)的插件。它基于 dart_service_provider
包,提供了几个有用的Widget来简化服务的注册和获取。本文将详细介绍如何使用 flutter_service_provider
插件,并提供一个完整的示例Demo。
主要特性
Services<T>
:构建服务提供器。ScopedServices<T>
:创建一个服务作用域。ServiceConsumer<T>
:将服务提供器传递给你的Widget构建器。ServiceInheritedWidget<T>
:共享IServiceProvider
实例给其子Widget。
获取 IServiceProvider
实例
- 通过
Services.of<T>(context)
:从最近的ServiceInheritedWidget<T>
获取IServiceProvider
实例。注意,Services<T>
和ScopedServices<T>
会创建ServiceInheritedWidget<T>
。 - 通过
ServiceConsumer<T>
:IServiceProvider
实例会通过builder
参数传递给子Widget。
单个根服务提供器
大多数应用程序只需要一个根服务提供器。在这种情况下,不需要指定泛型类型 T
,或者使用相同的 T
。
Services();
ScopedServices();
ServiceConsumer();
多个根服务提供器
如果应用程序需要多个隔离的服务提供器,可以通过不同的泛型类型 T
来区分它们。
class RootServiceProvider1 {}
Services<RootServiceProvider1>();
ScopedServices<RootServiceProvider1>();
ServiceConsumer<RootServiceProvider1>();
// 获取 RootServiceProvider1 的 IServiceProvider 实例
final serviceProvider = Services.of<RootServiceProvider1>(context);
class RootServiceProvider2 {}
Services<RootServiceProvider2>();
ScopedServices<RootServiceProvider2>();
ServiceConsumer<RootServiceProvider2>();
// 获取 RootServiceProvider2 的 IServiceProvider 实例
final serviceProvider = Services.of<RootServiceProvider2>(context);
使用示例
以下是一个完整的示例,展示了如何在Flutter应用中使用 flutter_service_provider
。
1. main.dart
import 'package:dart_service_logger/dart_service_logger.dart';
import 'package:dart_service_provider/dart_service_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_service_provider/flutter_service_provider.dart';
import 'src/services/services.dart';
void main() {
runApp(
// 使用 Services<T> 作为根
Services(
serviceConfig: (services) => services.addApplicationServices(),
builder: (context, _) => const MyApp(),
),
);
}
extension MyAppServiceCollectionExtensions on IServiceCollection {
void addApplicationServices() {
this
..addLogging(config: (b) => b.useLogger())
..addEnvironment(Environment(name: Environments.development))
..addHelloServices(); // 自定义服务注册
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
final logger = Services.of(context).getRequiredLogger<MyApp>();
logger.info("$MyApp is building");
return MaterialApp(
title: 'Flutter service Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: MyHomePage(title: "Flutter service example"),
);
}
}
2. MyHomePage
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late final String greetingMsg;
late final String greetingMsg2;
[@override](/user/override)
void initState() {
super.initState();
// 获取服务提供器并获取服务实例
final serviceProvider = Services.of(context);
final helloService = serviceProvider.getRequiredService<SingletonHelloService>();
final transientHelloService = serviceProvider.getRequiredService<TransientHelloService>();
// 初始化问候语
greetingMsg = helloService.greeting("Singleton");
greetingMsg2 = transientHelloService.greeting("Transient");
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(greetingMsg), // 显示单例服务的问候语
Text(greetingMsg2), // 显示瞬态服务的问候语
ElevatedButton(
onPressed: () {
// 导航到带有作用域的服务页面
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ScopedServices(
builder: (context, _) => const ScopeFeatureWidget(),
),
),
);
},
child: Text("Scoped Feature"),
),
],
),
),
);
}
}
3. ScopeFeatureWidget
class ScopeFeatureWidget extends StatelessWidget {
const ScopeFeatureWidget({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
// 获取服务提供器并获取作用域内的服务实例
final serviceProvider = Services.of(context);
final service1 = serviceProvider.getRequiredService<ScopeHelloService>();
final transientHelloService = serviceProvider.getRequiredService<TransientHelloService>();
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text("$ScopeFeatureWidget"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(service1.greeting("Scope")), // 显示作用域服务的问候语
Text(transientHelloService.greeting("Transient")), // 显示瞬态服务的问候语
ServiceConsumer(
builder: (context, p) {
final service2 = p.getRequiredService<ScopeHelloService>();
assert(identical(service1, service2),
"ServiceConsumer in ScopedServices widget should use the same IServiceProvider as ScopedServices");
return Text(service2.greeting("Consumer")); // 确保作用域内服务一致
},
),
ElevatedButton(
onPressed: () {
// 导航到新路由并保持相同的作用域
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return ServiceInheritedWidget(
provider: serviceProvider,
child: RouteAndScopedServicesWidget(),
);
},
),
);
},
child: Text("Same scope in new route"),
),
],
),
),
);
}
}
4. RouteAndScopedServicesWidget
class RouteAndScopedServicesWidget extends StatelessWidget {
const RouteAndScopedServicesWidget({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
final p = Services.of(context);
final service = p.getRequiredService<ScopeHelloService>();
return Scaffold(
appBar: AppBar(
title: Text("Scoped services in new route"),
),
body: Center(
child: Text(service.greeting("New Route")), // 显示新路由中的作用域服务问候语
),
);
}
}
更多关于Flutter服务提供插件flutter_service_provider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter服务提供插件flutter_service_provider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,flutter_service_provider
插件允许你定义和共享服务,使得不同的部分(如Widgets、ViewModels等)能够访问和使用这些服务。虽然这个插件的具体实现可能因版本而异,且在实际开发中可能需要自定义服务,但我可以给你一个基本的示例来展示如何使用这个插件(假设它提供了类似依赖注入的功能)。
首先,确保你的pubspec.yaml
文件中已经添加了flutter_service_provider
依赖(注意:实际插件名称可能不同,这里仅为示例):
dependencies:
flutter:
sdk: flutter
flutter_service_provider: ^x.y.z # 替换为实际版本号
然后,运行flutter pub get
来获取依赖。
接下来,我们将展示如何定义和使用一个服务。假设我们有一个简单的服务UserService
,它提供了一个获取用户信息的方法。
定义服务
// user_service.dart
class UserService {
String getUserInfo() {
return 'Hello, this is user info!';
}
}
提供服务
在你的应用中,你可能会有一个地方(如MaterialApp
的顶层)来提供这个服务。
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_service_provider/flutter_service_provider.dart'; // 假设插件提供这样的API
import 'user_service.dart';
void main() {
runApp(
ServiceProvider<UserService>(
create: (_) => UserService(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
在这个例子中,ServiceProvider
是一个假想的widget,用于提供UserService
实例。实际使用时,你可能需要根据flutter_service_provider
插件的实际API进行调整。
使用服务
在你的Widget中,你可以使用ServiceProvider.of
(或类似方法,取决于实际插件的API)来获取服务实例。
// home_screen.dart
import 'package:flutter/material.dart';
import 'package:flutter_service_provider/flutter_service_provider.dart'; // 假设插件提供这样的API
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final UserService userService = ServiceProvider.of<UserService>(context);
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Text(userService.getUserInfo()),
),
);
}
}
在这个例子中,ServiceProvider.of<UserService>(context)
用于从上下文中获取UserService
实例,并显示其返回的用户信息。
注意
- 上面的代码是基于假设的
flutter_service_provider
插件的API。实际使用时,请查阅该插件的官方文档以获取正确的使用方法和API。 - 如果
flutter_service_provider
插件不存在或不支持上述功能,你可能需要寻找其他依赖注入库(如get_it
或provider
)来实现类似的功能。 - 始终确保你的依赖项是最新的,并且与你的Flutter SDK版本兼容。