如何在Flutter中手动实现依赖注入?

时间:2018-05-12 14:51:39

标签: dependency-injection flutter

由于没有来自颤动团队的官方库,我正在尝试使用单例模式手动实现依赖注入,经过长时间的搜索,这就是我想出的:

var url = "http://keeng.vn/album/cho-anh-em-nhe-khanh-phong/osYbZ3ph.html";                
var web = new HtmlWeb();              
var doc = web.Load(url);

现在,class Injector{ Injector._internal(); static final _singleton = new Injector._internal(); factory Injector() => _singleton; SomeClass get someClass => new SomeClass(); } 是一个实例化后有一个实例的单例,Injector是我想在代码中注入的依赖项。上面的代码有效,但问题是我应该在哪里实例化SomeClass类并使其在我的代码中的每个位置都可用。你认为Injector在这种情况下是好还是有更好的方法?感谢。

2 个答案:

答案 0 :(得分:3)

要实现自己的依赖注入,我通常使用

的组合
  • A' Bindings'吸收所有注入服务的类
  • 一个静态getter / setter,它包含Bindings类的单个实例。这对于覆盖绑定非常重要。

返回类的getter如果有依赖项,应该懒惰地构造它们。这允许您通过扩展Bindings类并在全局绑定中设置它来覆盖图形的任何部分。例如,下面我有三个类,第三个类取决于前两个。

class Foo {}

class Bar {}

class Fizz {
  Fizz(this.foo, this.bar);

  final Foo foo;
  final Bar bar;
}


class Bindings {
  /// Can be final since there are no dependencies
  final Foo foo = new Foo();
  final Bar bar = new Bar();

  Fizz _fizz;
  Fizz get fizz {
    _fizz ??= new Fizz(foo, bar);
    return _fizz;
  }
}

Bindings get bindings => _bindings;
Bindings _bindings;
set bindings(Bindings value) {
  _bindings = value;
}

现在假设我想覆盖Foo进行测试。我可以扩展Bindings类并覆盖返回Foo的字段/ getter。在我的测试设置中,我使用这个新实例设置绑定。现在,当创建Fizz时,使用MockFoo实例而不是Foo

class MockFoo implements Foo {}

class BindingsOverride extends Bindings {
  @override
  final Foo foo = new MockFoo();
}

void main() {
  bindings = new BindingsOverride();
}

编辑:在早期版本中,我使用的是静态类。我不认为您需要通过绑定实例引用foobar,您可以直接引用成员。

答案 1 :(得分:0)

这是我解决此问题的方法。首先,我使用以下代码创建了一个名为injector.dart的dart文件:

// the singleton is private to this package
final _injector = new _Injector();
// expose depedencies
final foo = _injector.foo;
final bar = _injector.bar;

class _Injector{
    // create a singleton
    _Injector._internal();
    static final _singleton = new _Injector._internal();
    factory _Injector() {
        return _singleton;
    }

    // the dependecies
    Foo get foo => new Foo();
    Bar get bar => new Bar();
}

这就是代码的工作方式,首先我们创建一个单例类_Injector,创建所需的依赖项,然后使用顶级变量公开这些依赖项。这样,可以在injector.dart包可访问的任何地方访问依赖项。

你觉得伙计们怎么样?是好还是有更好的实施?感谢