java - 事后如何添加依赖注入(inject)?

标签 java android dependency-injection

我在开发当前的 Android 应用程序时学到了很多东西,足以看出我犯了一些错误。例如,我现在知道从测试的角度来看,下面的所有 new Blah(...) 语句都是不好的。是否有成熟的技术可以安全地迁移这样的现有代码以使用依赖注入(inject)的形式?我所说的“安全”是指应用程序破坏引擎盖的可能性很小。我正在考虑为每个依赖项添加 setter 方法,以便我可以在测试期间传入模拟对象,但这似乎有点 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");  


    }

}

最佳答案

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

我以前没有在 android 上做过这种重构,但在服务器端 java 项目中做过。您可以增量添加依赖项注入(inject)。开头:

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 现已注入(inject)并可测试。要删除 A 中的新调用,请替换

new B()

Global.objectGraph.get(B.class)

这有效地为您提供了完全重构的 B 和向后兼容的 A。当您删除对全局对象图的所有静态引用时,您可以将其删除。

关于java - 事后如何添加依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25254493/

相关文章:

java - 在企业应用程序 (EAI) 中将用户凭据存储在何处?

java - 在 JavaPoet 中使用继承的聪明方法

java - 如何在我的媒体播放器中实现 "pause"函数?

android - 如何在按下后退按钮时不结束应用程序

javascript - 将 Angular Controller 重构为单独的工厂和 Controller

c# - 如何在 JsonConverter 中注入(inject)/访问 HttpContext?

dependency-injection - DDD 中的唯一验证

java - SolrCrud存储库: use inheritance

java - 改造2 : Post multiple files with part names along with @FormUrlEncoded formData

java - Android - 按 ID 查找项目