You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart/Flutter中使用injectable实现通用工厂?

解决方案:实现通用工厂注册,避免重复编写工厂类

一、基于Injectable的优化方案

1. 注入函数类型替代工厂类

Injectable支持注入函数类型,通过定义通用函数别名,直接注入创建实例的函数,无需单独编写工厂类:

首先定义通用工厂函数的别名:

typedef FactoryFunc<T> = T Function();

然后编写业务类和实例创建函数:

import 'package:injectable/injectable.dart';

@singleton
class Foo {
  final FactoryFunc<Bar> _barFactory;

  // 直接注入创建Bar的函数
  Foo(this._barFactory);

  void doSomething() {
    var bar = _barFactory(); // 调用函数创建实例
    bar.blah();
  }
}

// 定义Bar的创建函数
@injectable
Bar createBar() => const Bar();

@injectable
class Bar {
  const Bar();

  void blah() {
    /* ... */
  }
}

最后在configureDependencies中注册函数类型(若自动生成未覆盖,可手动补充):

getIt.registerFactory<FactoryFunc<Bar>>(() => createBar);

2. 通用Factory类结合模块注册

如果你更倾向于保留工厂类结构,可以创建通用Factory<T>类,通过Injectable的模块集中注册,避免为每个类型编写单独工厂类:

// 通用工厂类
class Factory<T> {
  final T Function() create;
  const Factory(this.create);
}

// 模块类,集中注册所有工厂
@module
abstract class FactoriesModule {
  @injectable
  Factory<Bar> get barFactory => Factory(() => const Bar());

  // 其他类型的工厂直接在这里添加即可
  @injectable
  Factory<Baz> get bazFactory => Factory(() => Baz());
}

然后在Foo中注入对应的泛型工厂:

@singleton
class Foo {
  final Factory<Bar> _barFactory;

  Foo(this._barFactory);

  void doSomething() {
    var bar = _barFactory.create();
    bar.blah();
  }
}

二、换用GetIt直接实现(无需Injectable)

如果放弃Injectable,直接使用GetIt可以更灵活实现通用工厂:

  1. 注册工厂函数:
void configureDependencies() {
  final getIt = GetIt.instance;
  // 注册Bar的工厂函数,每次调用返回创建Bar的函数
  getIt.registerFactory<FactoryFunc<Bar>>(() => () => const Bar());
}
  1. 在业务类中注入并使用:
typedef FactoryFunc<T> = T Function();

class Foo {
  final FactoryFunc<Bar> _barFactory;

  Foo(this._barFactory);

  void doSomething() {
    var bar = _barFactory();
    bar.blah();
  }
}

注:若直接调用getIt<Bar>()(需用getIt.registerFactory(() => Bar())注册),虽能创建实例,但会让类直接依赖GetIt,不符合解耦原则,更推荐注入工厂函数的方式。

三、使用Riverpod实现(适用于Flutter)

如果是Flutter项目,Riverpod提供声明式依赖注入方案,同样可实现通用工厂:

  1. 定义工厂Provider:
import 'package:flutter_riverpod/flutter_riverpod.dart';

// 定义创建Bar的工厂Provider
final barFactoryProvider = Provider<Bar Function()>((ref) => () => const Bar());

class Bar {
  const Bar();
  void blah() {}
}
  1. 在消费类中注入使用:
class Foo {
  final Bar Function() _barFactory;

  Foo(this._barFactory);

  void doSomething() {
    var bar = _barFactory();
    bar.blah();
  }
}

// 在Widget或其他地方获取Foo实例时,传入工厂函数
final fooProvider = Provider<Foo>((ref) {
  final barFactory = ref.read(barFactoryProvider);
  return Foo(barFactory);
});

内容的提问来源于stack exchange,提问作者Tar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:35:02