What determines the lifecycle of a component (object graph) in Dagger 2? - java

I'm trying to wrap my head around scopes in Dagger 2, specifically the lifecycle of scoped graphs. How do you create a component that will be cleaned up when you leave the scope.
In the case of an Android application, using Dagger 1.x you generally have a root scope at the application level which you'd extend to create a child scope at the activity level.
public class MyActivity {
private ObjectGraph mGraph;
public void onCreate() {
mGraph = ((MyApp) getApplicationContext())
.getObjectGraph()
.plus(new ActivityModule())
.inject(this);
}
public void onDestroy() {
mGraph = null;
}
}
The child scope existed as long as you kept a reference to it, which in this case was the lifecycle of your Activity. Dropping the reference in onDestroy ensured the scoped graph was free to be garbage collected.
EDIT
Jesse Wilson recently posted a mea culpa
Dagger 1.0 badly screwed up its scope names ... The #Singleton annotation is used for both root graphs and custom graphs, so it's tricky to figure out what the actual scope of a thing is.
and everything else I've read/heard points towards Dagger 2 improving the way scopes work, but I'm struggling to understand the difference. According to #Kirill Boyarshinov's comment below, the lifecycle of a component or dependency is still determined, as usual, by concrete references. So is the difference between Dagger 1.x and 2.0 scopes purely a matter of semantic clarity?
My understanding
Dagger 1.x
Dependencies were either #Singleton or not. This was equally true of dependencies in the root graph and subgraphs, leading to ambiguity as to which graph the dependency was bound to (see In Dagger are Singletons within the sub-graph cached or will they always be recreated when a new activity sub-graph is constructed?)
Dagger 2.0
Custom scopes allow you to create semantically clear scopes, but are functionally equivalent to applying #Singleton in Dagger 1.x.
// Application level
#Singleton
#Component( modules = MyAppModule.class )
public interface MyAppComponent {
void inject(Application app);
}
#Module
public class MyAppModule {
#Singleton #Named("SingletonScope") #Provides
StringBuilder provideStringBuilderSingletonScope() {
return new StringBuilder("App");
}
}
// Our custom scope
#Scope public #interface PerActivity {}
// Activity level
#PerActivty
#Component(
dependencies = MyAppComponent.class,
modules = MyActivityModule.class
)
public interface MyActivityComponent {
void inject(Activity activity);
}
#Module
public class MyActivityModule {
#PerActivity #Named("ActivityScope") #Provides
StringBuilder provideStringBuilderActivityScope() {
return new StringBuilder("Activity");
}
#Name("Unscoped") #Provides
StringBuilder provideStringBuilderUnscoped() {
return new StringBuilder("Unscoped");
}
}
// Finally, a sample Activity which gets injected
public class MyActivity {
private MyActivityComponent component;
#Inject #Named("AppScope")
StringBuilder appScope
#Inject #Named("ActivityScope")
StringBuilder activityScope1
#Inject #Named("ActivityScope")
StringBuilder activityScope2
#Inject #Named("Unscoped")
StringBuilder unscoped1
#Inject #Named("Unscoped")
StringBuilder unscoped2
public void onCreate() {
component = Dagger_MyActivityComponent.builder()
.myApplicationComponent(App.getComponent())
.build()
.inject(this);
appScope.append(" > Activity")
appScope.build() // output matches "App (> Activity)+"
activityScope1.append("123")
activityScope1.build() // output: "Activity123"
activityScope2.append("456")
activityScope1.build() // output: "Activity123456"
unscoped1.append("123")
unscoped1.build() // output: "Unscoped123"
unscoped2.append("456")
unscoped2.build() // output: "Unscoped456"
}
public void onDestroy() {
component = null;
}
}
The takeaway being that using #PerActivity communicates your intention regarding the lifecycle of this component, but ultimately you can use the component anywhere/anytime. Dagger's only promise is that, for a given component, scope annotated methods will return a single instance. I also assume Dagger 2 uses the scope annotation on the component to verify that modules only provide dependencies that are either in the same scope or non-scoped.
In Summary
Dependencies are still either singleton or non-singleton, but #Singleton is now intended for application-level singleton instances and custom scopes are the preferred method for annotating singleton dependencies with a shorter lifecycle.
The developer is responsible for managing the lifecycle of components/dependencies by dropping references that are no longer needed and responsible for ensuring that components are only created once in the scope for which they are intended, but custom scope annotations make it easier to identify that scope.
The $64k Question*
Is my understanding of Dagger 2 scopes and lifecycles correct?
* Not actually a $64'000 question.

As for your question
What determines the lifecycle of a component (object graph) in Dagger 2?
The short answer is you determine it. Your components can be given a scope, such as
#Scope
#Retention(RetentionPolicy.RUNTIME)
public #interface ApplicationScope {
}
#Scope
#Retention(RetentionPolicy.RUNTIME)
public #interface ActivityScope {
}
These are useful for you for two things:
Validation of scope: a component can only have unscoped providers, or scoped providers of the same scope as your component.
.
#Component(modules={ApplicationModule.class})
#ApplicationScope
public interface ApplicationComponent {
Something something();
AnotherThing anotherThing();
void inject(Whatever whatever);
}
#Module
public class ApplicationModule {
#ApplicationScope //application-scoped provider, only one can exist per component
#Provides
public Something something() {
return new Something();
}
#Provides //unscoped, each INJECT call creates a new instance
public AnotherThing anotherThing() {
return new AnotherThing();
}
}
Allows for sub-scoping your scoped dependencies, thus allowing you to create a "subscoped" component that uses the provided instances from the "superscoped" component.
This can be done with #Subcomponent annotation, or component dependencies. I personally prefer dependencies.
#Component(modules={ApplicationModule.class})
#ApplicationScope
public interface ApplicationComponent {
Something something();
AnotherThing anotherThing();
void inject(Whatever whatever);
ActivityComponent newActivityComponent(ActivityModule activityModule); //subcomponent factory method
}
#Subcomponent(modules={ActivityModule.class})
#ActivityScope
public interface ActivityComponent {
ThirdThingy thirdThingy();
void inject(SomeActivity someActivity);
}
#Module
public class ActivityModule {
private Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
//...
}
ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
ActivityComponent activityComponent = applicationComponent.newActivityComponent(new ActivityModule(SomeActivity.this));
Or you can use component dependencies like so
#Component(modules={ApplicationModule.class})
#ApplicationScope
public class ApplicationComponent {
Something something();
AnotherThing anotherThing();
void inject(Whatever whatever);
}
#Component(dependencies={ApplicationComponent.class}, modules={ActivityModule.class})
#ActivityScope
public interface ActivityComponent extends ApplicationComponent {
ThirdThingy thirdThingy();
void inject(SomeActivity someActivity);
}
#Module
public class ActivityModule {
private Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
//...
}
ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
ActivityComponent activityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(SomeActivity.this)).build();
Important things to know:
A scoped provider creates one instance for that given scope for each component. Meaning a component keeps track of its own instances, but other components don't have a shared scope pool or some magic. To have one instance in a given scope, you need one instance of the component. This is why you must provide the ApplicationComponent to access its own scoped dependencies.
A component can subscope only one scoped component. Multiple scoped component dependencies are not allowed.

Related

Why does Dagger 2 force me to use #Provides instead of #Binds

I am looking into Dagger 2 (Java) right now and came across an issue right upon the start. Sadly, I was not able find a anything yet in the Dagger 2 Documentation or on Stackoverflow about it, so if you guys know some resources I would really appreciate it.
I prepared a minimal example within this repository here to explain whats my issue: https://github.com/stackoverflow-samples/dagger2-dependency-cycle
So we got an Application class that should be constructed
public class Application {
#Inject
public Application(SomeDependency one) {
}
public static void main(String[] args) {
DaggerApplicationComponent.create().build();
}
}
... with a dummy dependency
public class SomeDependency {
#Inject
public SomeDependency() {
}
}
And of course the Dagger classes/interfaces ...
.. a component interface:
#Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
Application build();
}
.. and a module:
#Module
abstract class ApplicationModule {
#Provides
static SomeDependency provideDepdendencyOne() {
return new SomeDependency();
}
}
What I dont get is why Dagger forces me to register SomeDepdendency with #Provides annotation and does not allow to register it via #Binds:
#Binds
abstract SomeDependency bindDepdendencyOne(SomeDependency one);
Whenever I change the code from #Provides to #Binds it gives me the following errors:
[Dagger/DependencyCycle] Found a dependency cycle:
io.github.codejanovic.dagger2.example.SomeDependency is injected at
io.github.codejanovic.dagger2.example.ApplicationModule.bindDepdendencyOne(one)
io.github.codejanovic.dagger2.example.SomeDependency is injected at
io.github.codejanovic.dagger2.example.Application(one)
io.github.codejanovic.dagger2.example.Application is provided at
io.github.codejanovic.dagger2.example.ApplicationComponent.build()
Being unable to #Bind an implementation makes absolutely no sense to me. What do I oversee?
Thanks in advance.
You're wrong in assuming that you need #Binds or #Provides in the first place. You can and should be using constructor injection—not the pattern, but the Dagger generates the code for me kind.
You already have the constructor annotated with #Inject, thus Dagger knows about the class and how to create it. There's nothing else to do.
public class SomeDependency {
#Inject
public SomeDependency() {
}
}
You don't need any #Provides, no #Binds, not even a #Module for this simple use case of yours. Your example should work right out of the box since both constructors are annotated with #Inject.
#Component
public interface ApplicationComponent {
Application build();
}
If you need to specify a scope you can add it on the class.
#Provides should be used for code that you can't use constructor injection for, or that needs additional setup. Of course you can create all the objects manually (as you're doing in your example) but this has no real benefit and will just produce a lot of boilerplate that can be avoided.
#Binds is to be used with implementations that you need to bind to an interface. Optimally you'd use constructor injection for the implementation as well, but you can as well add it to the component builder (#BindsInstance) or create it in a #Provides annotated method.
#Binds MyInterface bindMyImplementation(MyImplementation implementation);
If your class is marked with an #Inject constructor:
public class SomeDependency {
#Inject // <----
public SomeDependency() {
}
}
Then you need #Binds (or #Provides) only if you need to "bind" it as an implementation of an interface, or at least a different type than its concrete type.
Also, if your object has an #Inject constructor, you would not need to instantiate it in the module, because Dagger already knows how to instantiate it.
So to fix your code, all you need to do is:
// #Module
// abstract class ApplicationModule {
// #Provides
// static SomeDependency provideDepdendencyOne() {
// return new SomeDependency();
// }
// }
Solved.

Dagger 2 Singleton and Activity level dependencies

The issue I'm facing is about using App level and Activity level dependencies in single Activity.
Let's assume I have APP level dependency:
#Module
public class FormatModule {
#Provides
#Singleton
public DecimalFormat getDecimalFormat(){
DecimalFormat df = new DecimalFormat("0,000.00");
return df;
}
public class App extends Application {
private static AppComponent AppComponent;
public static AppComponent getAppComponent() {
return AppComponent;
}
#Override
public void onCreate () {
super.onCreate();
AppComponent = DaggerAppComponent
.builder()
.apiModule(new ApiModule())
.build();
}
}
and Component annotated #Singleton.
There is Activity level dependency:
#Module
public class MainActivityModule {
#Provides
Presenter getPresenter(){
return new Presenter();
}
#Component(modules = {MainActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
In MainActivity I initialise component with this code:
MainActivityComponent mainActivityComponent =
DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule())
.contextModule(new ContextModule(this))
.build();
mainActivityComponent.inject(this);
And in classes that use ony App level dependencies:
App.getAppComponent().inject(this);
The question is how can I use both App and Activity level dependencies in MainActivity?
To make this work, you need to establish a component dependency from your MainActivityComponent onto your AppComponent.
#Component(
modules = {MainActivityModule.class},
dependencies = {AppComponent.class}) // <-- this
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
This tells Dagger that it may call zero-arg methods on AppComponent to supply dependencies that MainActivityComponent needs, including dependencies of objects that MainActivity injects. This makes it particularly well-suited for depending on other Dagger components, since you can add those zero-arg methods onto AppComponent and Dagger will supply the implementations. However, for the sake of clarity or avoiding dependency cycles, you might also choose to list an interface as the dependency and then have a DaggerAppComponent implementation provided instead.
You'll need to supply an implementation of AppComponent as a part of ActivityComponent's builder:
MainActivityComponent mainActivityComponent =
DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule())
.contextModule(new ContextModule(this))
.appComponent(App.getAppComponent()) // <-- this
.build();
mainActivityComponent.inject(this);
Important: The only bindings available to you in MainActivityComponent will be the ones that are exposed as zero-arg methods on the interface or class that you list as a dependency ("provision methods"). If you supply a binding using a #Provides method on an AppComponent module, it will not appear in MainActivityComponent unless you add a getter for it on AppComponent itself. This allows you to be specific about what you inherit from AppComponent, but can be seen as a maintenance burden.
#Component(modules = ModuleA.class) public interface ComponentA {
BindingOne bindingOne();
}
#Module public abstract class ModuleA {
#Provides static BindingOne getBindingOne() { return BindingOne.INSTANCE; }
#Provides static BindingTwo getBindingTwo() { return BindingTwo.INSTANCE; }
}
// ComponentB has access to BindingOne but not BindingTwo, because it can only see
// what is available in ComponentA, not ComponentA's module set that includes ModuleA.
#Component(dependencies = ComponentA.class) public interface ComponentB { /* ... *}
Side notes
If MainActivityModule has a default constructor or other public no-arg constructor, you don't need to supply it in your builder. Dagger will create one for you.
getDecimalFormat and getPresenter don't use any instance state, so you can make them static; Dagger will detect this and make static calls instead of virtual method calls that are slightly slower on Android. If you switch all of your #Module methods to static #Provides or abstract #Binds methods, you can change your Module to an interface or abstract class, which means that Dagger can and will skip instantiating the method at all.
You need to list all of the bindings from AppComponent that you want on MainActivityComponent because Dagger can generate code for AppComponent and MainActivityComponent separately. As an alternative to component dependencies, you can choose to use subcomponents, where Dagger generates code for MainActivityComponent as an implementation detail of AppComponent, and you get your builder from AppComponent instead of a static method on DaggerMainActivityComponent. This establishes a tighter coupling between MainActivityComponent and AppComponent, but allows you to skip defining the zero-arg methods on AppComponent because Dagger can inspect what MainActivityComponent needs at compile time and provide those bindings privately.
One existing framework for a subcomponent hierarchy of Android Application/Activity/Fragment injection is dagger.android, which automates the creation and installation of subcomponents for each Android-created object including BroadcastReceiver, ContentProvider, and Service. As you get more comfortable with Dagger architecture, it may be something to consider.

Understanding the Dagger2 Flow (Sample provided)

I'm trying to wrap my head around the use of Dagger 2 in my project with Retrofit, RxJava, MVP implementation. However, I'm starting small by reading guides and watching videos and just when I thought I understood how it works, it appears I don't. Here is the sample I'm trying to understand.
Module:
#Module
public class AppModule {
private App app;
public AppModule(App app) {
this.app = app;
}
#Provides #Singleton public SharedPreferences provideSharedPreferences() {
return PreferenceManager.getDefaultSharedPreferences(app);
}
#Provides #Singleton public HelloModel provideHelloModel(SchedulerProvider schedulerProvider,
HelloDiskCache helloDiskCache, HelloService helloService, Clock clock) {
return new HelloModel(schedulerProvider, helloDiskCache, helloService, clock);
}
#Provides public HelloDiskCache provideHelloDiskCache(SharedPreferences prefs) {
return new HelloDiskCache(prefs);
}
#Provides public HelloService provideHelloService() {
return new HelloService();
}
#Provides public SchedulerProvider provideSchedulerProvider() {
return SchedulerProvider.DEFAULT;
}
#Provides public Clock provideClock() {
return Clock.REAL;
}
#Provides #Nullable public LayoutInflaterFactory provideLayoutInflaterFactory() {
return null;
}
Component
#Component(
modules = AppModule.class
)
#Singleton
public interface AppComponent {
HelloModel getHelloModel();
HelloDiskCache getHelloDiskCache();
MainActivity inject(MainActivity activity);
HelloFragment inject(HelloFragment fragment);
}
In the fragment, presenter is injected (where is this coming from?)
#Inject HelloPresenter presenter;
And in the presenter, there is a constructor injection
#Inject HelloPresenter(HelloModel helloModel) {
this.model = helloModel;
}
So, how come we can inject a presenter in the fragment, and why can we inject in the presenter? The answer does not have to be very elaborate I just feel stupid because I can't trace where it is coming from.
#Inject-annotated constructor is an alternative to a #Provides-annotated method for a dependency when there's not much configuration to do.
Since HelloPresenter has such constructor, Dagger discovers it automatically and is able to inject this dependency or use it to construct and provide other objects in the graph.
A class with an #Inject-annotated constructor can itself be annotated with a scope annotation (e.g., #Singleton). In this case, only components with the matching scope will be able to see it.
In general, this type of providing dependencies is less verbose, but not always you can use it (e.g., Activity, SharedPreferences). In such cases you have to go with a #Module and a #Provides method.
You can look at this sample where Dagger2 used with MVP Architecture
Dagger2 Android with MVP

Dagger2 component with more than one dependencies

This is what I currently have and it works:
#FragmentScope
#Component(dependencies = {FacebookComponent.class},
modules = {FragmentFacebookLoginModule.class})
public interface FragmentFacebookLoginComponent {
void inject(FragmentFacebookLogin fragment);
}
Now I want to add another dependency. I changed it to this:
#Component(dependencies = {FacebookComponent.class, AnotherComponent.class},
modules = {FragmentFacebookLoginModule.class})
But now I get this error message:
FragmentFacebookLoginComponent depends on more than one scoped
component
How can I solve this? How can I have more than one dependencies?
If I remove the scope from one component I get this error message:
AnotherComponent (unscoped) cannot depend on scoped components
I found the answer here: https://stackoverflow.com/a/29619594/1016472
At the end I created a AppComponent with the right scope and let FacebookComponent and AnotherComponent extends this AppComponent.
FacebookComponent and AnotherComponent does not have it's own scope (I removed it).
Looks now like this:
#AppScope
#Component
public interface AppComponent {
}
#Component(modules = {FacebookModule.class})
public interface FacebookComponent extends AppComponent {
}
#Component(modules = {AnotherModule.class})
public interface AnotherComponent extends AppComponent {
}
#FragmentScope
#Component(dependencies = {FacebookComponent.class, AnotherComponent.class},
modules = {FragmentFacebookLoginModule.class})
public interface FragmentFacebookLoginComponent {
void inject(FragmentFacebookLogin fragment);
}
You can't use scoped components in a dependencies array (which is quite strange I have to say), only unscoped, or one scoped + other unscoped.
But you can deceive dagger with "proxy" interfaces:
#Component
#Singleton
interface ComponentA {
fun provideSomeA()
}
interface ProxyComponentA : ComponentA
#Component
#Singleton
interface ComponentB {
fun provideSomeB()
}
interface ProxyComponentB : ComponentB
#Component(dependencies = [ProxyComponentA::class, ProxyComponentB::class])
#OtherScope
interface ComponentC
But in your ComponentC builder you should use proxy components implementations, which could easily be achieved with Kotlin:
class ProxyComponentAImpl(private val delegate: ComponentA) : ProxyComponentA, ComponentA by delegate
class ProxyComponentBImpl(private val delegate: ComponentB) : ProxyComponentB, ComponentB by delegate
componentA = DaggerComponentA.builder()...
componentB = DaggerComponentB.builder()...
componentC = DaggerComponentC.builder()
.componentA(ProxyComponentAImpl(componentA))
.componentB(ProxyComponentBImpl(componentB))
Works on dagger version 2.13, don't know about others
Also you could use vice versa inheritance ComponentA : ProxyComponentA to eliminate the need to create ProxyComponentAImpl, but it's not a good design choice if your ComponentA lays for example in a different gradle module
The solution was inspired by that issue discussion:
https://github.com/google/dagger/issues/1225
What you want to be determined to be within the ApplicationScope should be all defined without a scope, and linked together under the application scope only in the ApplicationComponent under the given scope.
For example,
#Component(modules = {FacebookModule.class})
public interface FacebookComponent {
FacebookThing facebookThing(); //assuming this is with #Provides in FacebookModule with NO SCOPE
}
#Component(modules = {AnotherModule.class})
public interface AnotherComponent{
AnotherThing anotherThing(); //assuming this is with #Provides in AnotherModule with NO SCOPE
}
Then you can do
#AppScope
#Component(dependencies={AnotherComponent.class, FacebookComponent.class})
public interface AppComponent extends AnotherComponent, FacebookComponent {}
After which you can do
#FragmentScope
#Component(dependencies=AppComponent.class)
public interface FragmentComponent extends AppComponent {}
Please note that unscoped providers create a new instance on every inject call. If you need the scoping, you should bind the modules to the same component, but components should only depend on other components with the intention of subscoping.
Now Dagger supports a component that can depends on more than 1 scoped dependencies. Just update your dagger version to 2.27
https://github.com/google/dagger/issues/1414
api 'com.google.dagger:dagger:2.27'
kapt 'com.google.dagger:dagger-compiler:2.27'
Include on your module the dependency module like this:
#Module(includes = FacebookModule.class)
public class AnotherModule {...

Dagger: No injectable members on android.content.Context. Do you want to add an injectable constructor? required by Class for Module

I am trying to convert my singleton CookieUtil to be injected with Dagger into LoginActivity. CookieUtil takes an application context therefor I have set up the following structure :
AndroidModule
#Module(
injects = {
CookieUtil.class,
LoginActivity.class
},
library = true
)
public class AndroidModule {
private final App application;
public AndroidModule(App application) {
this.application = application;
}
/**
* Allow the application context to be injected but require that it be annotated with
* {#link ForApplication #Annotation} to explicitly differentiate it from an activity context.
*/
#Provides
#Singleton
#ForApplication
Context provideApplicationContext() {
return application;
}
#Provides
#Singleton
CookieUtil provideCookieUtil() {
return new CookieUtil();
}
}
CookieUtil (What I want to inject into LoginActivity)
#Singleton
public class CookieUtil {
#Inject Context mContext; // gets injected with a app context. is this right ?
private PersistentCookieStore persistentCookieStore;
private CookieUtil() {
// use injected mContext
persistentCookieStore = new PersistentCookieStore(mContext);
// ...
}
}
LoginActivity (Where I want to inject CookieUtil)
public class LoginActivity extends BaseActivity {
#Inject CookieUtil cookieUtil;
#Override
protected void onCreate(Bundle savedInstanceState) {
// use CookieUtil ...
}
}
I have also set up all the bootstraping stuff from Dagger examples to enable everything to work
BaseActivity
public class BaseActivity extends ActionBarActivity {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perform injection so that when this call returns all dependencies will be available for use.
((App) getApplication()).inject(this);
}
}
App
public class App extends Application {
private ObjectGraph graph;
public void onCreate() {
super.onCreate();
graph = ObjectGraph.create(getModules().toArray());
// ...
}
protected List<Object> getModules() {
return Arrays.asList(
new AndroidModule(this),
new CupsModule() // Another module I haven't listed
);
}
public void inject(Object object) {
graph.inject(object);
}
}
ForApplication
#Qualifier
#Retention(RUNTIME)
public #interface ForApplication {
}
When I run the code, I get
No injectable members on android.content.Context. Do you want to add
an injectable constructor? required by CookieUtil for AndroidModule
What am I doing wrong ?
Everything still looks like magic to me as I don't fully aware of how to wire everything up, so detailed explanation would be very much appreciated.
Also, would be helpful if someone could point me to an explanation on dagger modules, when does it make sense to separate into two different modules ? What logical pieces do they usually bind ?
Thanks
EDIT
Changed suggested by Christian Gruber
#Singleton
public class CookieUtil {
private Context mContext;
private PersistentCookieStore persistentCookieStore;
#Inject
public CookieUtil(Context context) {
// use injected context
mContext = context
persistentCookieStore = new PersistentCookieStore(mContext);
// ...
}
}
Cookie cannot have a private constructor and still be created (provisioned) by Dagger. You can have a package-friendly constructor, and then it should work without #Provides CookiUtil .... Having the provides method for a class you control and could make injectable seems wasteful.
Generally speaking, Dagger considers a "binding" according to a "key" which is its type (with concrete type parameters, such as Foo<Bar>) along with any #Qualifier. So the type Foo<Bar> is different from #ForApplication Foo<Bar>. A binding is requested wherever #Inject occurs, and is supplied wherever #Provides occurs (or for unqualified bindings, if a class has an #Inject-marked constructor or fields, then an implicit binding is supplied. For every #Inject field or constructor parameter there must be a present binding for that key. Dagger needs to be able to see the methods it uses to create things, so generally private fields, methods, and constructors are not possible.
Also, please never simply inject Context without a qualifier. Or better, inject Application or Activity if that's the Context subtype you mean. Your graph WILL be impossible to manage if you don't distinguish between the 30,000 things that Android calls Context subtypes. (snark)

Categories