如何在事后添加依赖注入?

时间:2014-08-12 00:33:39

标签: java android dependency-injection

我已经学会了很多开发我当前的Android应用程序,足以看到我犯了一些错误。例如,我现在知道,从测试的角度来看,下面的所有new Blah(...)语句都是错误的。是否存在安全迁移现有代码以使用依赖注入形式的既定技术?安全"安全"我的意思是应用程序打破的可能性很低。我只想为每个依赖项添加setter方法,这样我就可以在测试期间传入mock对象,但这看起来有点像hackish。

@Override
public void onCreate() {
    super.onCreate();
    System.out.println("creating the LocationMonitorService");
    mBus = BusProvider.getInstance();
    mBus.register(this);
    markerRequestTimer = new GetMarkerRequestTimer(10*60000,10000);
    pushRequestTimer = new PushRequestTimer(10*60000,60000);
    deviceLocationClient = new DeviceLocationClient(this);
    gcmKeepAliveIntent = new Intent("com.gmail.npnster.first_project.gcmKeepAlive");
    gcmKeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, gcmKeepAliveIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    alarmManager = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
    alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, 4*60*1000, gcmKeepAlivePendingIntent);


}

class GetMarkerRequestTimer extends CountDownTimer {

    public GetMarkerRequestTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onTick(long millisUntilFinished) {
        System.out.println("requesting new markers from server");
        mBus.post(new GetMapMarkersRequest());

    }

    @Override
    public void onFinish() {
        System.out.println("time out reached ending request for markers from the server");  


    }

}

1 个答案:

答案 0 :(得分:2)

看到你在Android上,我假设你使用Dagger。如果使用Guice,请将ObjectGraph替换为Injector。其余的都一样。

我以前不必在android上进行这种重构,但已经在服务器端java项目中完成了。您可以逐步添加依赖注入。从:

开始
class A {
  B b = new B();
}

class B {
  C c = new C();
}

class C {
}

现在让我们假设我们想要重构B来使用DI,但不改变A的结构。

在中心位置创建一个新的ObjectGraph。使其成为静态和公共的(一般来说很糟糕,有利于增量转换)

public void onCreate()  {
    ObjectGraph objectGraph = ObjectGraph.create(new MyModule());
    Global.objectGraph = objectGraph; //Where global is just a class with a public static field called objectGraph
    MyApp app = objectGraph.get(App.class);
    ...
  }

所以现在你可以重构B:

class B {
  private final C c;
  @Inject
  B(C c) {
      this.c = c;
  }
}

B现在注射并可测试。要删除A中的新调用,请替换

new B()

Global.objectGraph.get(B.class)

它有效地为您提供了完全重构的B和向后兼容的A.当您,如果您摆脱了对全局对象图的所有静态引用,您可以删除它。