Dagger2场注入不起作用 [英] Dagger2 Field Injection not working

查看:113
本文介绍了Dagger2场注入不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我熟悉Spring依赖注入,但是Dagger2对我来说是新的。我试图使一个简单的Java应用程序正常工作,但字段注入无效。

I am familiar with Spring dependency injection, but Dagger2 is new to me. I am trying to get a simple java application working but field injection does not work.

我有一个类 Main ,这取决于类 MainBusiness ,而该类又取决于 MainDao

I have a class Main, that depends on a class MainBusiness which in turn depends on MainDao.

MainBusiness 被注入 Main 罚款,但 MainDao 不会注入到 MainBusiness 中,并抛出 NullPointerException

MainBusiness gets injected into Main fine, but MainDao does not get injected into MainBusiness and throws a NullPointerException.

这里是 MainDao ,它实现了接口 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 class

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

它将在上抛出NPE MainBusiness.getResource(MainBusiness.java:14)

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

What am I missing here? Appreciate any help I can get.

P.S这是一个普通的 Java 应用程序。它不是 Android 应用程序。

P.S This is a plain Java application. It is not an Android application.

推荐答案

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

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. Hence MainBusiness will still have an uninitialized DAO.

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

If you call new MainBusiness(); yourself you can't expect Dagger to take care of it. You should use constructor injection, and not call new yourself. 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.

这篇关于Dagger2场注入不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆