/* * Copyright (C) 2015 The Dagger Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package dagger.functional.cycle; import dagger.Binds; import dagger.Component; import dagger.Lazy; import dagger.Module; import dagger.Provides; import dagger.Subcomponent; import dagger.multibindings.IntoMap; import dagger.multibindings.StringKey; import java.util.Map; import javax.inject.Inject; import javax.inject.Provider; /** * Cycle classes used for testing cyclic dependencies. * *
 * {@literal A ← (E ← D ← B ← C ← Provider, Lazy), (B ← C ← Provider, Lazy)}
 * {@literal S ← Provider, Lazy}
 * 
*/ final class Cycles { private Cycles() {} static class A { public final B b; public final E e; @Inject A(E e, B b) { this.e = e; this.b = b; } } static class B { public final C c; @Inject B(C c) { this.c = c; } } static class C { public final Provider aProvider; @Inject public Lazy aLazy; @Inject public Provider> aLazyProvider; @Inject C(Provider aProvider) { this.aProvider = aProvider; } } static class D { public final B b; @Inject D(B b) { this.b = b; } } static class E { public final D d; @Inject E(D d) { this.d = d; } } static class S { public final Provider sProvider; @Inject public Lazy sLazy; @Inject S(Provider sProvider) { this.sProvider = sProvider; } } static class X { public final Y y; @Inject X(Y y) { this.y = y; } } static class Y { public final Map> mapOfProvidersOfX; public final Map> mapOfProvidersOfY; @Inject Y(Map> mapOfProvidersOfX, Map> mapOfProvidersOfY) { this.mapOfProvidersOfX = mapOfProvidersOfX; this.mapOfProvidersOfY = mapOfProvidersOfY; } } @Module abstract static class CycleMapModule { @Binds @IntoMap @StringKey("X") abstract X x(X x); @Binds @IntoMap @StringKey("Y") abstract Y y(Y y); } @SuppressWarnings("dependency-cycle") @Component(modules = CycleMapModule.class) interface CycleMapComponent { Y y(); } @SuppressWarnings("dependency-cycle") @Component(modules = CycleModule.class) interface CycleComponent { A a(); C c(); ChildCycleComponent child(); } @Module static class CycleModule { @Provides static Object provideObjectWithCycle(@SuppressWarnings("unused") Provider object) { return "object"; } } @SuppressWarnings("dependency-cycle") @Component interface SelfCycleComponent { S s(); } @Subcomponent interface ChildCycleComponent { @SuppressWarnings("dependency-cycle") A a(); @SuppressWarnings("dependency-cycle") Object object(); } interface Foo {} static class Bar implements Foo { @Inject Bar(Provider fooProvider) {} } /** * A component with a cycle in which a {@code @Binds} binding depends on the binding that has to * be deferred. */ @Component(modules = BindsCycleModule.class) interface BindsCycleComponent { Bar bar(); } @Module abstract static class BindsCycleModule { @Binds abstract Foo foo(Bar bar); } }