Flutter数据存储插件di_storage的使用

Flutter数据存储插件di_storage的使用

DiStorage 是一个轻量级的依赖注入库,适用于 dart。其主要优势在于代码量小(大约200行左右)。因此,你可以查看代码并确保它的工作原理。你也可以确定程序中不包含任何后门等。

特性

  • 注册(绑定)项目依赖并检索它们。
  • 取消注册(解绑)项目依赖。
  • 注册(绑定)依赖项的作用域。
  • 取消注册(解绑)依赖项的作用域。
  • 依赖项生命周期管理。

使用

要使用此插件,在你的 pubspec.yaml 文件中添加 di_storage 作为依赖。

示例

绑定、使用和移除依赖

DiStorage.shared.bind<SomeInterface>(
  module: null,
  () => SomeInterfaceImpl(),
  lifeTime: const LifeTime.single(),
);

DiStorage.shared.bind<SomeUsecase>(
  module: null,
  () => SomeUsecase(
    someInterface: di.resolve(),
  ),
  lifeTime: const LifeTime.prototype(),
);
// ...
final SomeInterface someInterface = DiStorage.shared.resolve();
final SomeUsecase someUsecase = DiStorage.shared.resolve();
// ...
// 当不再需要这些依赖时,可以选中移除它们
DiStorage.shared.remove<SomeInterface>();
DiStorage.shared.remove<SomeUsecase>();

绑定、使用和移除依赖项的作用域

class FirstDiScope extends DiScope {
  [@override](/user/override)
  void bind(DiStorage di) {
    di.bind<SomeInterface>(
      module: this,
      () => SomeInterfaceImpl(),
      lifeTime: const LifeTime.single(),
    );

    di.bind<SomeUsecase>(
      module: null,
      () => SomeUsecase(
        someInterface: di.resolve(),
      ),
      lifeTime: const LifeTime.prototype(),
    );
  }
}

class OtherDiScope extends DiScope {
  [@override](/user/override)
  void bind(DiStorage di) {
    di.bind<OtherInterface>(
      module: this,
      () => OtherInterfaceImpl(),
      lifeTime: const LifeTime.single(),
    );

    di.bind<OtherUsecase>(
      module: null,
      () => OtherUsecase(
        someInterface: di.resolve(),
      ),
      lifeTime: const LifeTime.prototype(),
    );
  }
}

/// 绑定
FirstDiScope().bind(DiStorage.shared);
OtherDiScope().bind(DiStorage.shared);

final SomeUsecase someUsecase = DiStorage.shared.resolve();
final OtherUsecase otherUsecase = DiStorage.shared.resolve();

// ...
// 使用 `someUsecase` 和 `otherUsecase`
// ...

// 移除 `OtherDiScope`
DiStorage.shared.removeScope<OtherDiScope>();

// ...
final isOtherUsecaseAvailable = DiStorage.shared.canResolve<OtherUsecase>();

// `isOtherUsecaseAvailable` = `false`

致谢

感谢 Sergei 激励我开发自己的库,以便完全控制其功能。


完整示例

以下是一个完整的示例代码,展示了如何使用 di_storage 插件。

import 'package:di_storage/di_storage.dart';
import 'package:example/domain/do_something_repository.dart';
import 'package:example/domain/model/token_info.dart';
import 'package:example/domain/usecases/do_something_usecase.dart';
import 'package:example/domain/usecases/session_info_provider_usecase.dart';
import 'package:example/domain/usecases/sign_out_usecase.dart';
import 'package:example/presentation/common_widgets/blocking_loading_indicator.dart';
import 'package:example/presentation/di/auth_di_scope.dart';
import 'package:example/presentation/di/unauth_di_scope.dart';
import 'package:example/presentation/home_screen/home_screen.dart';
import 'package:example/presentation/sign_in_screen/sign_in_screen.dart';
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

final navigatorKey = GlobalKey<NavigatorState>();

void main() {
  // [_installUnauthZoneDependencies] 安装应用程序未认证区域的依赖
  _installUnauthZoneDependencies();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final SessionInfoProviderUsecase sessionInfo = DiStorage.shared.resolve();

    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      themeMode: ThemeMode.light,
      debugShowCheckedModeBanner: false,
      showSemanticsDebugger: false,
      home: BlockingLoadingIndicator(
        child: StreamBuilder<TokenInfo>(
            stream: sessionInfo.sessionInfoStream.doOnData(
          (sessionInfo) {
            if (sessionInfo.isValid) {
              // [_installAuthZoneDependencies] 安装应用程序认证区域的依赖
              _installAuthZoneDependencies();
            } else {
              // [_dropAuthZoneDependencies] 删除未认证区域中未使用的依赖
              _dropAuthZoneDependencies();
            }
          },
        ), builder: (context, snapshot) {
          final isAuthorized = snapshot.data?.isValid == true;

          // 展示在未认证区域中没有未使用的依赖
          if (!isAuthorized) {
            assert(
              DiStorage.shared.tryResolve<DoSomethingRepository>() == null,
            );

            assert(
              DiStorage.shared.tryResolve<DoSomethingUsecase>() == null,
            );

            assert(
              DiStorage.shared.tryResolve<SignOutUsecase>() == null,
            );
          }

          return Navigator(
            key: navigatorKey,
            pages: [
              if (isAuthorized)
                MaterialPage(
                  child: HomeScreen(
                    doSomethingUsecase: DiStorage.shared.resolve(),
                    signOutUsecase: DiStorage.shared.resolve(),
                  ),
                )
              else
                MaterialPage(
                  child: SignInScreen(
                    signInUsecase: DiStorage.shared.resolve(),
                  ),
                ),
            ],
            onPopPage: (route, result) {
              if (!route.didPop(result)) {
                return false;
              }

              if (navigatorKey.currentState?.canPop() == true) {
                return true;
              }

              return false;
            },
          );
        }),
      ),
    );
  }

  Future<void> onRoute(BuildContext context, Object action) async {}
}

/// [_installUnauthZoneDependencies] 安装应用程序未认证区域的依赖
void _installUnauthZoneDependencies() {
  final di = DiStorage.shared;
  UnauthDiScope().bind(di);
}

/// [_installAuthZoneDependencies] 安装应用程序认证区域的依赖
void _installAuthZoneDependencies() {
  final di = DiStorage.shared;
  AuthDiScope().bind(di);
}

/// [_dropAuthZoneDependencies] 删除未认证区域中未使用的依赖
void _dropAuthZoneDependencies() {
  DiStorage.shared.removeScope<AuthDiScope>();
}

更多关于Flutter数据存储插件di_storage的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据存储插件di_storage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用di_storage插件进行数据存储的示例代码。di_storage是一个轻量级的Flutter插件,用于本地数据存储,支持简单的键值对存储。

第一步:添加依赖

首先,你需要在你的pubspec.yaml文件中添加di_storage的依赖。

dependencies:
  flutter:
    sdk: flutter
  di_storage: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

第二步:导入并使用di_storage

在你的Dart文件中导入di_storage,并进行数据存储和读取操作。

import 'package:flutter/material.dart';
import 'package:di_storage/di_storage.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('DiStorage Example'),
        ),
        body: Center(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DiStorage storage = DiStorage();
  String? storedValue;

  @override
  void initState() {
    super.initState();
    // 从存储中读取数据
    storage.get<String>('my_key').then((value) {
      setState(() {
        storedValue = value;
      });
    });
  }

  void _saveData() async {
    // 存储数据
    await storage.set<String>('my_key', 'Hello, Flutter!');
    setState(() {
      storedValue = 'Data saved!';
    });
  }

  void _retrieveData() async {
    // 从存储中读取数据
    String? value = await storage.get<String>('my_key');
    setState(() {
      storedValue = value ?? 'No data found';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(storedValue ?? 'Loading...'),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: _saveData,
          child: Text('Save Data'),
        ),
        SizedBox(height: 10),
        ElevatedButton(
          onPressed: _retrieveData,
          child: Text('Retrieve Data'),
        ),
      ],
    );
  }
}

代码解释

  1. 添加依赖:在pubspec.yaml文件中添加di_storage依赖。
  2. 导入包:在需要使用di_storage的Dart文件中导入package:di_storage/di_storage.dart
  3. 创建实例:创建一个DiStorage实例。
  4. 存储数据:使用storage.set<T>(key, value)方法存储数据。这里的<T>是值的类型,key是键,value是要存储的值。
  5. 读取数据:使用storage.get<T>(key)方法读取数据。这是一个异步操作,返回一个Future<T?>
  6. 更新UI:使用setState方法在数据读取或存储后更新UI。

这个示例展示了如何使用di_storage插件进行简单的数据存储和读取操作。你可以根据实际需求扩展这个示例,比如存储复杂的数据结构或者处理更多的数据类型。

回到顶部