简体   繁体   中英

Dagger 2 Module Override in Subcomponent

I have app with Subcomponent s like this

-------- ApplicationComponent ------------
        |                    |
        |                    |
        |                    |
    Service Component      Activity Component
                              |
                              |
                              |
                           Fragment Component

Everything works fine, but I want to do one thing. Android M requires runtime permissions so I decided to create Controller , something like helper class that will be injected into Fragment or Activity` Common Interface

public interface PermissionController {

    boolean hasPermissionInManifest(String permissionName);

    boolean isPermissionGranted(String permission);

/**
 * Request permission for Android 6
 *
 * @param permission  permission that is requested
 * @param requestCode request code
 * @return if user is going to be asked about permission so we need to handle callback, otherwise
 * user was already asked or permission is not required cause of android lower version
 */
boolean requestPermission(int requestCode, String permission);

    void requestPermissions(int requestCode, String... permissions);

}

And one method from different implementations PermissionActivityManager and PermissionFragmentManager

   @Override
    public boolean requestPermission(int requestCode, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (mContext.checkSelfPermission(permission)
                    != PackageManager.PERMISSION_GRANTED) {
                mContext.requestPermissions(new String[]{permission},
                        requestCode);
                return true;
            }
        }
        return false;
    }

And Fragment implementation

   @Override
    public boolean requestPermission(int requestCode, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(mFragment.getActivity(), permission)
                    != PackageManager.PERMISSION_GRANTED) {
                mFragment.requestPermissions(new String[]{permission},
                        requestCode);
                return true;
            }
        }
        return false;
    }

Hope you got an idea.

But about the problem, my FragmentComponent is subcomponent of ActivityComponent

They both have PermissionModule

@PerActivity
@Subcomponent(
        modules = {
                ActivityModule.class,
                PermissionModule.class
        })
public interface ActivityComponent {
    Activity activity();

    FragmentComponent fragmentComponent(FragmentModule module);

    void inject(BaseActivity baseActivity);

    void inject(MainAppActivity mainAppActivity);

}

And for Fragment

@Subcomponent(
        modules = {
                FragmentModule.class,
                ProviderModule.class,
                PermissionModule.class
        })
@PerFragment
public interface FragmentComponent {
    Fragment fragment();

    void inject(BaseFragment baseFragment);

}

And modules are the same except annotations and returned instances.

@PerFragment
@Module
public class PermissionModule {
    @PerFragment
    @Provides
    PermissionController providePermissionController(Fragment fragment) {
        return new PermissionFragmentManager(fragment);
    }
}

@PerActivity
@Module
public class PermissionModule {
    @PerActivity
    @Provides
    PermissionController providePermissionController(Activity activity) {
        return new PermissionActivityManager(activity);
    }
}

So my question is - if there is any way to override provide method used in parent component or there is another way to solve the problem ? Because in my case PermissionActivityManager was injected.

@Subcomponent inherits all bindings from the superscoped component. In this case, that is the @ActivityScope component.

If you want to control the inherited dependencies, you have to use Component Dependencies. Component dependencies allow you to inherit only the bindings specified by the provision methods.

If you don't want to tinker with new builders, then I'd recommend using @Named("activity") and @Named("fragment") annotation to specify the type of permission handler you'd like to inject. You have to put it on your @Inject annotated field and on the @Provides annotated method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM