Dagger注入超类和子类

时间:2016-12-26 06:17:39

标签: android kotlin dagger-2

BaseFragment类

open class BaseFragment : Fragment() {

    @Inject lateinit var apiManager: ApiManager
    @Inject lateinit var eventBus: EventBus

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        App.getInstance().component.inject(this)
    }

    override fun onStop() {
        eventBus.unreg(this)
        super.onStop()
    }

    override fun onStart() {
        super.onStart()
        eventBus.reg(this)
    }
}

RoomsFragment class

class RoomsFragment : BaseFragment() {

    @Inject lateinit var roomAdapter: RoomsAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        App.getInstance().component.inject(this)
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater?.inflate(R.layout.fragment_rooms_fragment_new, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        recyclerView.adapter = roomAdapter //This line throws null or lateinit property roomAdapter has not been initialized
    }
}

AdapterModule类

@Module(includes = AppModule.class)
public class AdapterModule {

    @Provides //App module has EventBus so i included it in Module
    RoomsAdapter provideRoomsAdapter(EventBus eventBus) {
        return new RoomsAdapter(eventBus);
    }
}

AppComonent类

@Singleton
    @Component(modules = {AppModule.class, AdapterModule.class})
    public interface ApplicationComponent {
        void inject(ApiManager apiManager);
        void inject(BaseFragment baseFragment);
    }

正如您所看到的,我试图在超类和子类中注入对象,但它并没有按预期工作。 BaseFragment注入的对象可以找到,但RoomsFragment注入失败。有解决方案吗

修正: 我忘了在ApplicationComponent中为子类RoomsFragment添加接口。由于它的超类BaseFragment接口存在,因此在编译时没有抛出任何错误。

@Singleton
    @Component(modules = {AppModule.class, AdapterModule.class})
    public interface ApplicationComponent {
        void inject(RoomsFragment roomsFragment);
        void inject(ApiManager apiManager);
        void inject(BaseFragment baseFragment);
    }

2 个答案:

答案 0 :(得分:5)

@Component文档中的members injection methods文档描述了相关行为。

看起来你正试图注入RoomsFragment的成员。通过添加一个接受RoomsFragment的方法,您将注入@Inject RoomsFragment成员和任何超类型(在本例中为`BaseFragment)。

另一方面,如果您调用接受BaseFragment的成员注入方法,则会注入@Inject成员BaseFragment,但任何成员任何子类型的成员。因此,为抽象类型定义成员注入方法几乎不是一个好主意。

在最初的问题中,由于所有成员注入方法都被定义为彼此的重载,因此这很复杂。这意味着根据过载的解析方式,您将获得给定类型的不同注入行为。有关这些重载容易出错的更多背景信息,请参阅 Effective Java 2:Item 41

值得注意的是,在原始代码示例中有ApiManager的成员注入方法,但该类型作为实例注入BaseFragment。注入成员可以传递地解析依赖关系,因此不需要为组件上的ApiManager定义任何方法。

因此,为了注入RoomsFragment的所有成员(声明和隐含),只需为RoomsFragment定义一个成员注入方法:

@Singleton
@Component(modules = {AppModule.class, AdapterModule.class})
public interface ApplicationComponent {
  void inject(RoomsFragment roomsFragment);
}

答案 1 :(得分:0)

试试这个:

@Singleton
        @Component(modules = {AppModule.class, AdapterModule.class})
        public interface ApplicationComponent {
            void inject(ApiManager apiManager);
            void inject(BaseFragment baseFragment);
            void inject(RoomsFragment roomsFragment);
        }