如何注入到使用匕首静态类? [英] How to inject into static classes using Dagger?

查看:312
本文介绍了如何注入到使用匕首静态类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过匕首介绍依赖注入到项目。下面code作为一个例子来描述的注入静态类

I want to introduce dependency injection through Dagger to a project. The following code acts as an example to describe the problem of injection into static classes.

静态方法 setupTextView()从多个类名为:

The static method setupTextView() is called from multiple classes:

public abstract class TextViewHelper {
    public static void setupTextView(TextView textView, 
                                     Spanned text, 
                                     TrackingPoint trackingPoint) {
        textView.setText(text, TextView.BufferType.SPANNABLE);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyApp.getTracker().track(trackingPoint);
            }
        });
    }
}

下面是一个例子如何使用辅助方法:

Here is one example how the helper method is used:

TextViewHelper.setupTextView(this, R.id.some_text_view, 
                             R.string.some_text,
                             TrackingPoint.SomeTextClick);

在辅助方法中使用的跟踪是由应用程序类提供的:

The tracking used in the helper method is provided by the application class:

public class MyApp extends Application {

    private static Tracking mTracking;

    public void onCreate() {
        super.onCreate();
        mTracking = getTracking(getApplicationContext());
    }

    private Tracking getTracking(Context context) {
        if (BuildConfig.DEBUG) {
            return new NoTracking();
        } else {
            return new NsaTracking(context);
        }
    }

    public static Tracking getTracker() {
        return mTracking;
    }

}

现在,我想通过匕首注入跟踪。当我重构了code我发现我需要从我的活动或片段静态助手通过跟踪对象,因为我不能直接注入到静态类:

Now, I want to inject the tracking via Dagger. When I refactored the code I noticed that I would need to pass the tracking object from my Activity or Fragment to the static helper since I cannot directly inject into the static class:

TextViewHelper.setupTextView(this, R.id.some_text_view, 
                             R.string.some_text, 
                             TrackingPoint.SomeTextClick,
                             Tracking tracking);

这并不觉得自己是一个好的设计模式 - 因为我通过了指点杆跟踪对象。你会如何​​改善呢?

This does not feel like a good design pattern - since I pass the TrackPoint and the Tracking object. How would you improve this?

推荐答案

在你的 TextViewHelper 创建一个静态字段与跟踪。

In your TextViewHelper create a static field with the tracker.

public class TextViewHelper {

    private TextViewHelper(){}

    @Inject
    static Tracking sTracker;

    public static void setupTextView(TextView textView, 
                                     Spanned text, 
                                     TrackingPoint trackingPoint) {
        textView.setText(text, TextView.BufferType.SPANNABLE);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sTracker.track(trackingPoint);
            }
        });
    }
}

下面是如何配置模块:

@Module(staticInjections = TextViewHelper.class)
public class TrackerModule {
...
}

和你的图最重要的,通话injectStatics。

And the most important, call injectStatics on your graph.

mObjectGraph = ObjectGraph.create(new TrackerModule());
mObjectGraph.injectStatics();

编辑:

当你注意到匕首的文档指出静态注射的应该是因为静态依赖难以测试和重用谨慎使用。的它是所有真正的,但因为你问如何注入对象转换成实用类这是最好的解决方案。

As you noted Dagger's documentation states that static injections "should be used sparingly because static dependencies are difficult to test and reuse." It is all true, but because you asked how to inject object into utility class this is the best solution.

但是,如果你希望你的code是更容易测试,创建一个类似如下模块:

But if you want your code to be more testable, create a module like below:

@Module(injects = {classes that utilizes TextViewHelper})
public class TrackerModule {

      @Provides
      Tracking provideTracker() {
           ...
      }

      @Provides
      @Singleton
      TextViewHelper provideTextViewHelper(Tracking tracker) {
           return new TextViewHelper(tracker);
      }
}

现在,你可以删除静态 TextViewHelper 方法,因为这个工具类将使用匕首被注入。

Now you can remove static from TextViewHelper methods because this utility class will be injected using dagger.

public class TextViewHelper {

    private final Tracking mTracker;

    public TextViewHelper(Tracking tracker){
        mTracker = tracker;
    }

    public void setupTextView(TextView textView, 
                              Spanned text, 
                              TrackingPoint trackingPoint) {
         ...
    }
}

这是怎样,如果你想跟着好的做法是应该做的事。这两种解决方案将工作,所以它是由你来选择一个。

This is how it should be done if you want to follow good practices. Both solution will work so it's up to you to choose one.

这篇关于如何注入到使用匕首静态类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆