2016-06-13 12 views
0

Ich arbeite an mehreren app, die Verbindung mit der gleichen API, so habe ich beschlossen, gemeinsame Klassen zu erstellen, legen Sie sie in ein Modul und teilen sie unter allen Projekten.Dolch inject falsche Klasse (inject Eltern statt Kind-Klasse)

Zum Beispiel habe ich Klassen wie folgt in meinem Anteil Modul

// This is a bass class, no application will use it. 
public class GetPlayerInteractor extends ApiInteractor { 

    @Inject 
    public GetPlayerInteractor(ThreadExecutor threadExecutor, 
          PostExecutionThread postExecutionThread, 
          RestClient restClient, 
          RequestTokenInteractor requestTokenInteractor) { 
    super(threadExecutor, postExecutionThread, restClient, requestTokenInteractor); 
    } 
} 

// This class will accept GetPlayerInteractor or its children class as argument. 
public class PlayerAuthenticationInteractor extends ApiInteractor { 

    @Inject 
    public PlayerAuthenticationInteractor(ThreadExecutor threadExecutor, 
             PostExecutionThread postExecutionThread, 
             RestClient restClient, 
             RequestTokenInteractor requestTokenInteractor, 
             GetPlayerInteractor getPlayerInteractor) { 
    super(threadExecutor, postExecutionThread, restClient, requestTokenInteractor, 
     getPlayerInteractor); 
    } 
} 

und in der Anwendung, die das Modul umfasst

// This one is the actual class I need to inject 
public class GetPlayerByEmailInteractor extends GetPlayerInteractor { 

    private GetDomainNameInteractor getDomainNameInteractor; 

    @Inject 
    public GetPlayerByEmailInteractor(ThreadExecutor threadExecutor, 
            PostExecutionThread postExecutionThread, 
            RestClient restClient, 
            RequestTokenInteractor requestTokenInteractor, 
            GetDomainNameInteractor getDomainNameInteractor) { 
    super(threadExecutor, postExecutionThread, restClient, requestTokenInteractor, getPlayerCustomFieldsInteractor); 

    this.getDomainNameInteractor = getDomainNameInteractor; 
    } 
} 

Und das ist die UserModule in der Anwendung

@Module 
public class UserModule { 

    @Provides 
    @PerActivity 
    GetPlayerInteractor provideGetPlayerInteractor(ThreadExecutor threadExecutor, 
               PostExecutionThread postExecutionThread, 
               RestClient restClient, 
               RequestTokenInteractor requestTokenInteractor, 
               GetDomainNameInteractor getDomainNameInteractor) { 
    Log.i("Dev", "Create GetPlayerInteractor"); 
    return new GetPlayerByEmailInteractor(threadExecutor, postExecutionThread, restClient, requestTokenInteractor, getDomainNameInteractor); 
    } 

    @Provides 
    @PerActivity 
    PlayerAuthenticationInteractor providePlayerAuthenticationInteractor(ThreadExecutor threadExecutor, 
                     PostExecutionThread postExecutionThread, 
                     RestClient restClient, 
                     RequestTokenInteractor requestTokenInteractor, 
                     GetPlayerByEmailInteractor getPlayerByEmailInteractor) { 
    Log.i("Dev", "Create PlayerAuthenticationInteractor"); 
    return new PlayerAuthenticationInteractor(threadExecutor, postExecutionThread, restClient, requestTokenInteractor, getPlayerByEmailInteractor); 
    } 
} 

Und ich schreibe nie @Provide für GetPlayerInteractor, weil es nur eine Basisklasse BU ist t aus irgendeinem Grund, GetPlayerByEmailInteractor nie erstellt, anmelden beide Provide-Methoden nie drucken (auch Break-Point, den ich nie umschalten) und ich habe getPlayerInteractor als Argument von PlayerAuthen anstelle von getPlayerByEmailInteractor.

Auch, wenn ich beide

@Provide 
@PerActivity 
GetPlayerInteractor provideGetPlayerInteractor(...) 

und

entfernen
@Provide 
@PerActivity 
PlayerAuthenticationInteractor providePlayerAuthenticationInteractor(...) 

Der Build noch Erfolg, und die App kann

laufen Wenn ich DaggerApplicationComponent anschaue, sehe ich, wie folgend

public final class DaggerApplicationComponent implements ApplicationComponent { 
    // Some other classes 
    private Provider<GetPlayerInteractor> getPlayerInteractorProvider; 
    private Provider<PlayerAuthenticationInteractor> playerAuthenticationInteractorProvider; 
    // Some other classes 
    private Provider<GetPlayerByEmailInteractor> getPlayerByEmailInteractorProvider; 
    // Some other classes 

    private void initialize(final Builder builder) { 
    // Some other classes 
    this.getPlayerInteractorProvider = ... 
    this.playerAuthenticationInteractorProvider = PlayerAuthenticationInteractor_Factory.create((MembersInjector) MembersInjectors.noOp(), provideThreadExecutorProvider, providePostExecutionThreadProvider, provideRestClientProvider, provideRequestTokenInteractorProvider, getPlayerInteractorProvider); 
    // Some other classes 
    this.getPlayerByEmailInteractorProvider = ... 

    } 
} 

Beachten Sie, dass der Lass-Parameter, der an PlayerAuthenticationInteractor_Factory übergeben wird, getPlayerInteractorProvider anstelle von getPlayerByEmailInteractorProvider ist.

Was ich falsch liege.

Antwort

1
UserPresenter provideUserPresenter(GetUserUseCase getUserUseCase) 

Will Dolch sagen, dass Sie eine GetUserUseCase wollen.

@Inject 
public GetEmployeeUseCase() 

@Inject 
public GetEmployeeUseCase() 

Beide Ihre GetUserUseCase und sein Kind kann durch Konstruktor Injektion bereitgestellt werden, aber da Sie eine GetUserUseCase angefordert das ist, was Sie erhalten.

Wenn Sie nicht GetUserUseCase verwenden möchten, fordern Sie es nicht an. Der einfache Weg wäre Sie bieten auf diese Methode zu beheben:

UserPresenter provideUserPresenter(GetEmployeeUseCase getUserUseCase) 

Welche Art von Ordnung ist, da die Logik der was Sie bieten noch in einem Modul und nicht in Ihrer Geschäftslogik. Wenn Sie/wollen Ihre übergeordnete Klasse müssen liefern, entfernen Sie die @Provides daraus und machen ein Verfahren wie das bietet folgende Dolch zu sagen, über die Unterklasse, die Sie verwenden möchten:

@Provides GetUserUseCase provideUserUseCase(GetEmployeeUseCase getUserUseCase) { 
    return getUserUseCase; 
} 

Dies wird nur Ihre Unterklassenimplementierung Karte zur Elternklasse. Wenn Sie nicht die @Inject Annotation auf Ihrem Eltern entfernen, führt dies zu einigen mehrere bietet Methoden ... Fehler.

+0

Hallo David, danke für deine Antwort, aber leider funktioniert es nicht, weil die Methode, um UserPresenter bereitzustellen, ich bereits für GetEmployeeUseCase-Klasse anfordern. Ich werde den Code mit meinen tatsächlichen Klassen aktualisieren, damit es besser ist zu sehen, was ich verpasst habe. –

+0

Frage aktualisiert, sorry für die tatsächlichen Klassen am Anfang nicht zur Verfügung stellen. –

+0

@ Tar_Tw45 Bitte entfernen Sie die '@ Inject'-Annotationen für Ihre Klassenkonstruktoren. Wie erwähnt, Ihr Objekt ist wahrscheinlich Konstruktor injected-> Ihre Methode liefert wird ignoriert –