2017-05-06 85 views
2

我正在学习Dagger 2,所以我想了解一些基本的东西。我有以下代码:如何声明依赖关系

@Module 
public class MainModule { 

@Provides 
public Presenter provideMainActivityPresenter(Model model){ 
    return new MainPresenter(model); 

} 

@Provides 
public Model provideMainModel(){ 
    return new MainModel(); 
} 
} 

和我MainPresenter类看起来是这样的:

public class MainPresenter implements Presenter { 

@Nullable 
private ViewImpl view; 
private Model model; 



public MainPresenter(Model model) { 
    this.model = model; 
} 

@Override 
public void setView(ViewImpl view) { 
    this.view = view; 
    } 
} 

,而不是上面的代码,可能我这样做?

public class MainPresenter implements Presenter { 

@Nullable 
private ViewImpl view; 

@Inject 
Model model; 


@Override 
public void setView(ViewImpl view) { 
    this.view = view; 
} 
} 

因为MainPresenter依赖于Model,它不是@Nullable
或者这是错误的?

我不明白时,我应该把依赖作为一个构造函数参数,或者当我应该使用@Inject

+0

看起来你需要了解Dagger的基础知识。试试这个教程:https://www.techyourchance.com/dagger-tutorial/ – Vasiliy

回答

4

你已经基本上3的方式来使用匕首

  • 构造方法注入
  • 场注射
  • 从模块自己提供它

(也有创建对象后调用方法的方法注入)


以下是使用提供类的模块。虽然没有错,但这是编写和维护的最大开销。您可以通过将所请求的依赖关系创建对象并返回它:

// in a module 

@Provides 
public Presenter provideMainActivityPresenter(Model model){ 
    // you request model and pass it to the constructor yourself 
    return new MainPresenter(model); 
} 

这应该与需要额外设置的东西,比如GsonOkHttp,或Retrofit这样就可以在一个地方与创建对象使用所需的依赖关系。


下将用于注射,你没有访问或不想使用constructo对象。您注释字段,在组件注册的方法注入你的对象:

@Component class SomeComponent { 
    void injectPresenter(MainPresenter presenter); 
} 

public class MainPresenter implements Presenter { 

    // it's not annotated by @Inject, so it will be ignored 
    @Nullable 
    private ViewImpl view; 

    // will be field injected by calling Component.injectPresenter(presenter) 
    @Inject 
    Model model; 

    // other methods, etc 
} 

这也将为您提供开销所有的类都在一个主持人注册,当你不能使用构造应使用,像活动,片段或服务。这就是为什么所有这些Dagger示例都有这些onCreate() { DaggerComponent.inject(this); }方法来注入Android框架的一部分。


最重要的是你可以使用构造函数注入。你用@Inject注释构造函数,并让Dagger找出如何创建它。

public class MainPresenter implements Presenter { 

    // not assigned by constructor 
    @Nullable 
    private ViewImpl view; 

    // assigned in the constructor which gets called by dagger and the dependency is passed in 
    private Model model; 

    // dagger will call the constructor and pass in the Model 
    @Inject 
    public MainPresenter(Model model) { 
    this.model = model; 
    } 
} 

这只需要你注释你的类的构造函数和匕首将知道如何处理它,因为所有的依赖(构造函数的参数,在这个例子中模式)可以提供。


上述所有将创建一个对象和方法可以/应当在不同的情况下使用。

所有这些方法或者将依赖关系传递给构造函数,或者直接注入@Inject注释字段。应该在构造函数中使用依赖关系,或者使用@Inject注释,以便Dagger知道它们。

我还写了一篇关于the basic usage of Dagger 2的博客文章,并提供了一些进一步的细节。

+0

所以:如果需要额外的设置像Retrofit,Gson我可以使用模块中的提供并在我需要使用的类中使用Inject我可以在构造函数中使用Inject? – ste9206

+1

@ ste9206没错。如果你可以修改构造函数,你可以使用构造函数注入,如果需要安装,使用一个模块,并且如果你不能访问构造函数(例如Activities),则使用该组件注册一个'inject(MyActivity a)'。 –

+0

所以注入(...)也很好用于碎片和服务,当然? – ste9206