| /* |
| * 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. |
| * |
| * <pre> |
| * {@literal A ← (E ← D ← B ← C ← Provider<A>, Lazy<A>), (B ← C ← Provider<A>, Lazy<A>)} |
| * {@literal S ← Provider<S>, Lazy<S>} |
| * </pre> |
| */ |
| 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<A> aProvider; |
| @Inject public Lazy<A> aLazy; |
| @Inject public Provider<Lazy<A>> aLazyProvider; |
| |
| @Inject |
| C(Provider<A> 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<S> sProvider; |
| @Inject public Lazy<S> sLazy; |
| |
| @Inject |
| S(Provider<S> sProvider) { |
| this.sProvider = sProvider; |
| } |
| } |
| |
| static class X { |
| public final Y y; |
| |
| @Inject |
| X(Y y) { |
| this.y = y; |
| } |
| } |
| |
| static class Y { |
| public final Map<String, Provider<X>> mapOfProvidersOfX; |
| public final Map<String, Provider<Y>> mapOfProvidersOfY; |
| |
| @Inject |
| Y(Map<String, Provider<X>> mapOfProvidersOfX, Map<String, Provider<Y>> 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> 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<Foo> 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); |
| } |
| } |