Dagger2 Field Injection无法正常工作

时间:2017-11-11 19:51:24

标签: java dependency-injection dagger-2

我熟悉Spring依赖注入,但Dagger2对我来说是新手。我试图让一个简单的Java应用程序工作,但是字段注入不起作用。

我有一个班级Main,这取决于班级MainBusiness,而班级MainDao又取决于MainBusiness

Main被注入MainDao罚款,但MainBusiness未被注入NullPointerException并抛出MainDao

以下是实现interface IMainDao

public class MainDao implements IMainDao { @Inject public MainDao() { } public String getResource() { return "This is the resource you are looking for"; } }
MainBusiness

以下是实施IMainBusiness

public class MainBusiness implements IMainBusiness { // package friendly field. @Inject IMainDao mainDao; @Inject public MainBusiness() { } public String getResource() { return mainDao.getResource(); // throws NPE here. } }
AppModule

以下是@Module public class AppModule { /** * Provides a singleton instance of the MainDao * * @return */ @Provides @Singleton public IMainDao providesMainDao() { return new MainDao(); } /** * Provides a singleton instance of the MainBusiness Class * * @return */ @Provides @Singleton public IMainBusiness providesMainBusiness() { return new MainBusiness(); } }

AppComponent

@Singleton @Component(modules = {AppModule.class}) public interface AppComponent { /** * @param main */ void inject(Main main); }

Main

public class Main { @Inject IMainBusiness mainBusiness; public Main() { AppComponent dac = DaggerAppComponent.builder().build(); dac.inject(this); } public static void main(String args[]) { Main main = new Main(); System.out.println(main.mainBusiness.getResource()); } }

MainBusiness.getResource(MainBusiness.java:14)

它会在Java

上抛出一个NPE

我在这里缺少什么?感谢我能得到的任何帮助。

P.S这是一个普通的Android应用程序。它不是final Snackbar mySnackbar = Snackbar.make(findViewById(R.id.bottom_sheet_page), R.string.map_undoremove, Snackbar.LENGTH_LONG); View snackbarView = mySnackbar.getView(); snackbarView.setElevation(30); 应用程序。

1 个答案:

答案 0 :(得分:7)

字段注入将注入您传入的对象的字段。someComponent.inject(someObject)将注入someObject的字段,但它不会传递依赖注入。因此MainBusiness仍会有未初始化的DAO。

如果你自己致电new MainBusiness();,你不能指望Dagger照顾它。你应该使用构造函数注入,而不是自己调用new。模块用于绑定或其他设置,并且应该减少自己调用所有构造函数的样板。

我冒昧地切换到构造函数注入并完全删除了字段注入,因为您的用例不需要它。 (也许有一些错字,我没有编译它)

@Singleton
public class MainDao implements IMainDao
{       
    @Inject
    public MainDao()
    {
    }
}

@Singleton
public class MainBusiness implements IMainBusiness
{
    private IMainDao mainDao;

    @Inject
    public MainBusiness(IMainDao mainDao)
    {
        this.mainDao = mainDao;
    }
}

@Module
interface AppModule {

    @Binds IMainBusiness bindBusiness(MainBusiness impl);

    @Binds IMainDao bindDao(MainDao impl);

}

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent
{
    //  -> no reason not to use constructor injection here as well
    Main getMain(); // provision method
}

public class Main
{   

    private IMainBusiness mainBusiness;

    // favor constructor injection
    @Inject
    public Main(IMainBusiness mainBusiness)
    {
        this.mainBusiness = mainBusiness;
    }

    public static void main(String args[])
    {
        AppComponent component = DaggerAppComponent.builder().build()
        Main main = component.getMain();
        System.out.println(main.mainBusiness.getResource());
    }
}

我建议你再看看一些指南,以确保你理解这些概念,或者你可能为自己创造了比必要更多的工作。最近我还写了一篇文章,试着clear up some misconceptions about Dagger