Flutter插件factory_castle的探索使用

发布于 1周前 作者 itying888 最后一次编辑是 5天前 来自 Flutter

Flutter插件factory_castle的探索使用

Dart的IoC容器,受Castle Windsor启发+Flutter MVVM框架。

Pub Version Pub Version test codecov

IoC和DI

设置

IoC/DI包是平台无关的,因此可以在命令行应用程序和Flutter中使用。

只需将其添加到您的pubspec.yaml文件中:

dependencies:
  factory_castle:

创建容器

import 'package:factory_castle/factory_castle.dart';

final container = FactoryContainer(); 

组件注册

如名称所示,组件作为工厂委托注册到容器中。必须手动将依赖项注入构造函数(幸运的是,Dart会帮助你)。

可以使用反射来避免手动注入,但遗憾的是,dart:mirrors库不适用于Flutter。非Flutter应用的反射支持可能稍后通过单独的包引入。

让我们注册一个接受LoggerConfig对象作为参数的MyService

container.register<MyService>((c) => MyService(c.res<Logger>(), c.res<Config>()));

Dart擅长类型推断,因此如果依赖类型的参数类型相同,则无需显式指定依赖类型。如果您不想用任何接口抽象注册的组件,也可以省略注册组件类型。

下一个示例与前一个示例完全相同:

container.register((c) => MyService(c.res(), c.res()));

每个工厂委托都会收到当前FactoryContainer实例的快捷包装,以便可以通过res<>()方法将依赖项注入构造函数。

组件是惰性解析的,这使得注册顺序不重要。查看完整的示例:

container.register((c) => MyService(c.res(), c.res()));
container.register((c) => Logger());
container.register((c) => Config(String.fromEnvironment('Flavor')));

目前还不支持在多个接口下注册组件。建议使用以下解决方法:

final logger = FileLogger();
container.register<ILogger>((c) => logger);
container.register<Logger>((c) => logger);

获取组件

调用FactoryContainer.resolve<>()并传入组件类型以从容器中获取它。

final repo = container.resolve<UserRepository>();

生命周期

可以通过FactoryContainer.register()的可选参数指定组件生命周期:

container.register((c) => CacheEntry(c.res(), c.res()), lifestyle: Lifestyle.Transient);

目前有两个生命周期选项。

单例

当第一次调用resolve<>()时,组件的工厂委托被调用一次。每次后续调用都返回相同的实例。这是默认的生命周期。

瞬态

每次调用resolve<>()时,组件的工厂委托都被调用。目前还没有办法指定动态参数。

名称

您可以指定组件名称,以便在需要时解析此特定组件。

container.register<ILogger>((c) => DbLogger(), name: 'DbLogger');
container.register<ILogger>((c) => FileLogger(), name: 'FileLogger');

// ...

final fileLog = container.resolve<ILogger>(name: 'FileLogger');

组件覆盖

默认情况下,每个未命名注册的组件都会覆盖前一个组件。这不是最终设计,将来可能会更改。目前,您可以注册多个未命名的组件,并期望在resolve<>()时获取最后一个组件。

container.register<ICacheFactory>((c) => DefaultCacheFactory());
container.register<ICacheFactory>((c) => MyCacheFactory());

final cacheFactory = container.resolve<ICacheFactory>(); // MyCacheFactory

当同时注册命名和未命名组件时,这种行为不一致。

容器处置

容器和组件的处置尚未实现。

容器层次结构

Flutter状态管理和MVVM

根部件

视图

视图模型

服务定位器

获取TickerProvider

示例

食谱

路线图

计划的功能。

参数化瞬态组件创建

container.registerTransient((c, p) => CacheEntry(p['key'], c.res()));

// ...

final entry = container.resolve<CacheEntry>(params: { 'key': key });

在多个接口下注册组件

container.register<IStorage, FileStorage>((c) => FileStorage(/*...*/));

注册时将组件标记为默认

container.register((c) => FileStorage(/*...*/, asDefault: true));

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

1 回复

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


在探索Flutter中未知的插件,比如factory_castle时,理解其功能和用法是非常重要的。虽然factory_castle可能不是一个广为人知的插件,但我们可以基于Flutter插件的一般使用方法来探索它。假设factory_castle是一个用于依赖注入或工厂模式实现的插件,以下是如何在Flutter项目中集成和使用它的一个示例。

首先,确保你已经在pubspec.yaml文件中添加了factory_castle依赖:

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

然后运行flutter pub get来获取依赖。

示例代码

以下是一个简单的示例,展示了如何使用factory_castle(假设它支持依赖注入)。由于我无法直接访问factory_castle的内部实现细节,我将提供一个假设性的代码示例,这个示例基于依赖注入的一般概念。

1. 定义服务接口和实现

// service_interface.dart
abstract class MyService {
  void doSomething();
}

// service_implementation.dart
class MyServiceImpl implements MyService {
  @override
  void doSomething() {
    print("Doing something in MyServiceImpl");
  }
}

2. 配置factory_castle

假设factory_castle提供了一个注册和获取依赖的方式,我们可以这样配置它:

// main.dart
import 'package:flutter/material.dart';
import 'package:factory_castle/factory_castle.dart';  // 假设的导入路径
import 'service_interface.dart';
import 'service_implementation.dart';

void main() {
  // 假设FactoryCastle有一个全局注册器
  var container = FactoryCastle();

  // 注册服务
  container.registerSingleton<MyService>(MyServiceImpl());

  runApp(MyApp(container: container));
}

class MyApp extends StatelessWidget {
  final FactoryCastle container;

  MyApp({required this.container});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 从容器中获取服务实例
    var myService = context.dependOnInheritedWidgetOfExactType<FactoryCastle>()!.resolve<MyService>();

    return Scaffold(
      appBar: AppBar(
        title: Text('Factory Castle Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            myService.doSomething();
          },
          child: Text('Call MyService'),
        ),
      ),
    );
  }
}

注意:上面的代码有几个假设:

  • FactoryCastle有一个全局注册器。
  • FactoryCastle可以被InheritedWidget包装,以便在Flutter的widget树中访问。
  • resolve<T>()方法用于从容器中解析服务。

实际上,这些假设可能并不准确,因为factory_castle的具体API和实现细节未知。你需要查阅factory_castle的官方文档或源代码来了解其确切的用法。

结论

在Flutter中集成和使用未知插件时,最佳做法是查阅该插件的官方文档、示例代码或源代码。上述示例提供了一个假设性的使用场景,但具体的实现和API调用可能会根据factory_castle的实际功能而有所不同。如果factory_castle支持依赖注入或其他功能,你应该能够找到相应的注册、解析和使用服务的方法。

回到顶部