简体   繁体   English

Dagger2场注入不起作用

[英]Dagger2 Field Injection not working

I am familiar with Spring dependency injection, but Dagger2 is new to me. 我熟悉Spring依赖注入,但是Dagger2对我来说是新的。 I am trying to get a simple java application working but field injection does not work. 我正在尝试使一个简单的Java应用程序正常工作,但是字段注入无效。

I have a class Main , that depends on a class MainBusiness which in turn depends on MainDao . 我有一个Main类,它依赖于MainBusiness类,而MainBusiness类又依赖于MainDao

MainBusiness gets injected into Main fine, but MainDao does not get injected into MainBusiness and throws a NullPointerException . MainBusiness被注入Main罚款,但MainDao没有被注入MainBusiness并抛出NullPointerException

Here is the MainDao that implements an interface IMainDao 这里是MainDao实现的interface IMainDao

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

    public String getResource()
    {
        return "This is the resource you are looking for";
    }
}

Here is the MainBusiness that implements IMainBusiness 这里是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.
    }

}

Here is the AppModule 这是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();
    }
}

The AppComponent AppComponent

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent
{

    /**
     * @param main
     */
    void inject(Main main); 
}

And the Main class 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());
    }
}

It throws an NPE on MainBusiness.getResource(MainBusiness.java:14) 它在MainBusiness.getResource(MainBusiness.java:14)上抛出NPE

What am I missing here? 我在这里想念什么? Appreciate any help I can get. 感谢我可以获得的任何帮助。

PS This is a plain Java application. PS这是一个普通的Java应用程序。 It is not an Android application. 这不是一个Android应用程序。

Field injection will inject the fields of the object you pass in. someComponent.inject(someObject) will then inject the fields of someObject , but it does not inject the dependencies transitively. 字段注入将注入您传入的对象的字段someComponent.inject(someObject)随后将注入someObject的字段,但不会过渡注入依赖项。 Hence MainBusiness will still have an uninitialized DAO. 因此, MainBusiness仍将具有未初始化的DAO。

If you call new MainBusiness(); 如果您调用new MainBusiness(); yourself you can't expect Dagger to take care of it. 自己,您不能指望Dagger会照顾好它。 You should use constructor injection, and not call new yourself. 您应该使用构造函数注入,而不要自己调用new Modules are for bindings, or additional setup, and should reduce the boilerplate of calling all the constructors yourself. 模块用于绑定或其他设置,应减少自己调用所有构造函数的样板。

I took some liberty to switch to constructor injection and completely remove field injection, since it is not needed for your use case. 我有一些自由可以切换到构造函数注入并完全删除字段注入,因为在您的用例中不需要。 (Maybe there's some typo, I did not compile it) (也许有错别字,我没有编译)

@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());
    }
}

I suggest that you have another look at some guides to make sure you understand the concepts, or you might be creating more work for yourself than necessary. 我建议您再看看一些指南,以确保您理解这些概念,否则您可能会为自己创建更多不必要的工作。 I also wrote a post recently where I try to clear up some misconceptions about Dagger . 我最近还写了一篇文章,试图消除对Dagger的误解

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM