【问题标题】:How to use dependecy injection in flutter?如何在颤振中使用依赖注入?
【发布时间】:2017-10-23 05:26:54
【问题描述】:

我想使用 di。在颤振中,我添加了这个 https://pub.dartlang.org/packages/di 打包我的项目,我开始阅读这篇 https://webdev.dartlang.org/angular/guide/dependency-injection 文章,但我并不完全理解。

所以没关系: 在服务类(例如:MyServices)上使用@Injectable() 注释,但是如何注入其他类? 例如我想类似:

class MyClass{
   //some variable
   var asd = MyService.asd; //need inject var.
                            //maybe use injector.get(MyService).asd; 
                            //but how add injector? (I don't add across constructor)

   MyService.oneMethod;//need inject method
}

main(){
    var injector = new ModuleInjector([new Module()
       ..bind(MyService)
    ]);
}

关键是,我不想使用构造函数。我想直接使用注射器。这在颤振/飞镖中是可能的吗?

【问题讨论】:

    标签: android angularjs dependency-injection dart flutter


    【解决方案1】:

    Google 最近开源了一个兼容 Flutter 的依赖注入框架。可在此处获得:https://github.com/google/inject.dart

    本项目提供静态编译时依赖注入,而不是依赖反射在运行时注入依赖。如果你熟悉Dagger,它看起来很相似。

    值得注意的是 - 这不是 Google 或 Dart 团队的官方项目。在撰写本文时,文档很少,目前被认为是开发者预览版。

    【讨论】:

      【解决方案2】:

      Angulars DI 包不能独立于 Angular 使用。

      di 包已经过时了,它依赖于 dart:mirrors,这在 Flutter 中不可用

      似乎有一个新的 DI 包正在进行中,它应该取代 Angulars 内置的 DI,也应该可以在 Flutter 或服务器端应用程序中独立使用,但还没有可用的预发布或源代码.

      更新

      宣布的 DI 包被无限期推迟。

      【讨论】:

      • 多次提到他们即将提前预览新的 DI 包。我也希望“很快”很快;-)
      • 您可以尝试使用ng_di 包或类似包。它使用代码生成器和装饰器来获得相同的行为。
      【解决方案3】:

      如果你想将一个类用作 Singleton,从我所见,常见的用例是使用工厂构造函数。

      How do you build a Singleton in Dart?

      暂时不必在 Flutter 中使用任何依赖注入系统。

      【讨论】:

      • +1 用于使用语言功能并避免不必要的包。我认为您也可以通过在构造函数/方法上创建可选参数并将默认值设置为实现抽象类的对象来进行自己的 DI。这样你就可以在测试期间传入一个模拟的实现。
      【解决方案4】:

      你好,这样的事情怎么样?非常简单的实现,Injector 本身是单例的,并且还添加了类。当然可以很容易地扩展。如果您正在寻找更复杂的东西,请查看此包:https://pub.dartlang.org/packages/flutter_simple_dependency_injection

      void main() {  
        Injector injector = Injector();
        injector.add(() => Person('Filip'));
        injector.add(() => City('New York'));
      
        Person person =  injector.get<Person>(); 
        City city =  injector.get<City>();
      
        print(person.name);
        print(city.name);
      }
      
      class Person {
        String name;
      
        Person(this.name);
      }
      
      class City {
        String name;
      
        City(this.name);
      }
      
      
      typedef T CreateInstanceFn<T>();
      
      class Injector {
        static final Injector _singleton =  Injector._internal();
        final _factories = Map<String, dynamic>();
      
        factory Injector() {
          return _singleton;
        }
      
        Injector._internal();
      
        String _generateKey<T>(T type) {
          return '${type.toString()}_instance';
        }
      
        void add<T>(CreateInstanceFn<T> createInstance) {
          final typeKey = _generateKey(T);
          _factories[typeKey] = createInstance();
        }
      
        T get<T>() {
          final typeKey = _generateKey(T);
          T instance = _factories[typeKey];
          if (instance == null) {
            print('Cannot find instance for type $typeKey');
          }
      
          return instance;
        }
      }
      

      【讨论】:

        【解决方案5】:

        我在这里遇到了同样的问题,所以我专门为 Flutter 创建了一个 dart 包。它依赖于工厂方法而不是镜像 api,因此它可以在颤振中工作。虽然仍然使用熟悉的 IOC 模式。希望这会有所帮助!

        https://pub.dartlang.org/packages/flutter_simple_dependency_injection

        import 'package:flutter_simple_dependency_injection/injector.dart';
        
        void main() {
          final injector = Injector.getInjector();
          injector.map(Logger, (i) => new Logger(), isSingleton: true);
          injector.map(String, (i) => "https://api.com/", key: "apiUrl");
          injector.map(SomeService, (i) => new SomeService(i.get(Logger), i.get(String, "apiUrl")));
        
          injector.get(SomeService).doSomething();
          // passing in the [SomeService] as a generic parameter strongly types the return object.
          injector.get<SomeService>(SomeService).doSomething();
        }
        
        class Logger {
          void log(String message) => print(message); 
        }
        
        class SomeService {
          final Logger _logger;
          final String _apiUrl;
        
          SomeService(this._logger, this._apiUrl);
        
          void doSomething() {
            _logger.log("Doing something with the api at '$_apiUrl'");
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-09-15
          • 1970-01-01
          • 2020-08-25
          • 1970-01-01
          • 1970-01-01
          • 2013-01-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多