eC Droid
eC Droid

Reputation: 681

Dagger2 How to @Provide one type with two different implementations

I'm very new to Dagger2 just starting. I want to achieve something like this but no success.

Here is my module

@Module
public class UtilModule
{
    @Provides
    @Named("fragmentUtilActivity")
    public FragmentUtils providesFragmentUtilForActivity(Context context)
    {
        return new FragmentUtils(context);
    }

    @Provides
    @Named("fragmentUtilFragment")
    FragmentUtils providesFragmentUtilForFragment(Fragment fragment)
    {
        return new FragmentUtils(fragment);
    }

}

And this is my component

@Component(modules = UtilModule.class)
public interface UtilComponent
{
    @Named("fragmentUtilActivity")
    FragmentUtils fragmentUtilsActivity(Context context);

    @Named("fragmentUtilFragment")
    FragmentUtils fragmentUtilsFragment(Fragment fragment);
}

And this is my FragmentUtil class

package myms.utils;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;

import javax.inject.Inject;

import myms.R;

public class FragmentUtils
{
    private Context context;

    private Fragment hostFragment;

    public FragmentUtils(Context context)
    {
        this.context = context;
    }

    public FragmentUtils(Fragment hostFragment)
    {
        this.hostFragment = hostFragment;
    }

    public void addFragment(Fragment fragment, boolean addToBackStack)
    {
        FragmentTransaction transaction = ((Activity) context).getFragmentManager()
                                                              .beginTransaction();
        transaction.add(R.id.fragment_container, fragment, null);

        if(addToBackStack)
        {
            transaction.addToBackStack(null);
        }

        transaction.commit();
    }

    public void addNestedFragment(Fragment fragment, boolean addToBackStack)
    {
        FragmentTransaction transaction = hostFragment.getChildFragmentManager().beginTransaction();
        transaction.add(R.id.nested_fragment_container, fragment, null);

        if(addToBackStack)
        {
            transaction.addToBackStack(null);
        }

        transaction.commit();
    }

    public void replaceNestedFragment(Fragment fragment, boolean addToBackStack)
    {
        FragmentTransaction transaction = hostFragment.getChildFragmentManager().beginTransaction();
        transaction.replace(R.id.nested_fragment_container, fragment, null);

        if(addToBackStack)
        {
            transaction.addToBackStack(null);
        }

        transaction.commit();
    }
}

What i want is to use the instance of fragmentUtils with two different implementation One is for activity and other for fragment. Please guide me what am i doing wrong.

Also can some one please help me understand the purpose of void inject(SomeClass) in @Component interface.

Regards

Upvotes: 1

Views: 119

Answers (1)

eC Droid
eC Droid

Reputation: 681

Okay after trying hard i'm able to solve it by modifying my UtilMoudle class

package myms.modules;

import android.app.Fragment;
import android.content.Context;

import javax.inject.Named;

import dagger.Module;
import dagger.Provides;
import myms.utils.FragmentUtils;


@Module
public class UtilModule
{
    private Context context;

    private Fragment fragment;


    public UtilModule(Context context)
    {
        this.context = context;
    }

    public UtilModule(Fragment fragment)
    {
        this.fragment = fragment;
    }

    @Provides
    @Named("fragmentUtilActivity")
    public FragmentUtils providesFragmentUtilForActivity(Context context)
    {
        return new FragmentUtils(context);
    }

    @Provides
    @Named("fragmentUtilFragment")
    FragmentUtils providesFragmentUtilForFragment(Fragment fragment)
    {
        return new FragmentUtils(fragment);
    }

    @Provides
    Context provideContext()
    {
        return context;
    }

    @Provides
    Fragment provideFragment()
    {
        return fragment;
    }

}

so basically i have to provide the dependencies for my methods like context and fragment in my case. Then finally to get the instance i have to do like this. For example for activity

UtilComponent component = DaggerUtilComponent.builder()
                                                     .utilModule(new UtilModule(this))
                                                     .build();
        FragmentUtils fragmentUtils = component.fragmentUtilsActivity();

Please note .utilModule(new UtilModule(this)) as this will provide the context while building the graph.

I'm very new into this Dagger thing so please use this approach with care. No warranties / No claims applicable. Happy Daggering :)

Upvotes: 2

Related Questions