2016-04-01 16 views
1

Erstens, ich bin Neuling, gerade zu erkunden, Dolch, ich habe ein paar Probleme mit dem Verständnis, so hoffe jemand kann mir helfen.Dolch 2 Scopes Erklärung

Ich habe viel über Dolch gelesen, kann aber immer noch einige Teile nicht herausfinden.

Ich habe meine ApplicationComponent und es sieht aus wie dieses

@Singleton 
@Component(modules = { 
     ApplicationModule.class, 
     ThreadingModule.class, 
     NetworkModule.class, 
     DatabaseModule.class, 
     ServiceModule.class, 
     ParseModule.class, 
     PreferencesSessionModule.class}) 

public interface ApplicationComponent { 
    void inject(BaseActivity baseActivity); 
    void inject(MainAppActivity mainAppActivity); 
    void inject(BaseFragment baseFragment); 
} 

Und es funktioniert super alles richtig spritzt, aber jetzt möchte ich tiefer in Dolch API und Custom Scope

I PermissionModule genannt haben Modul verwenden tauchen Es wird für Android M-Versionen verwendet.

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

Und ich will es in meiner Tätigkeit injiziert werden und nur in der Erinnerung sein, wenn die Aktivität auch im Speicher (actvity Lifecycle)

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

    void inject(BaseActivity baseActivity); 

    PermissionModule permissionModule(); 
} 

Mein ActivityComponent

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

    void inject(BaseActivity baseActivity); 

    PermissionModule permissionModule(); 
} 

Und meine BaseActivity

public abstract class BaseActivity extends AppCompatActivity implements SpiceManagerProvider, NetworkRequestsExecutor { 
    // Dependencies are injected by ApplicationComponent 
    @Inject 
    protected ApplicationSettingsManager mApplicationSettingsManager; 
    @Inject 
    protected SpiceManager mSpiceManager; 
    @Inject 
    protected ScheduledThreadPoolExecutor mPoolExecutor; 

    !!!!!! 
    Should be injected by activity component 
    @Inject 
    protected PermissionController mPermissionController; 

Und in onCreate()

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // Injecting dependencies 
     MyApplication application = MyApplication.get(this); 
     application.getApplicationComponent().inject(this); 
     DaggerActivityComponent.builder().activityModule(new ActivityModule(this)).build().inject(this); 
     mPermissionController.requestPermission(Manifest.permission.ACCESS_FINE_LOCATION); 
     mPermissionController.requestPermission(Manifest.permission.CAMERA); 
     super.onCreate(savedInstanceState); 
    } 

bekam ich den Fehler

PermissionController kann nicht ohne @ Provides- oder @ Erzeugt-kommentierten Verfahren bereitgestellt werden. .ui.activities.base.BaseActivity.mPermissionController

Was in meinem Code falsch?

Auch keine neue Frage zu erstellen und es ist zu diesem Thema verwandt.

Wie analysiert dagger2 Scope Annotation, ich kann das nicht herausfinden. Wie ich verstehe, Dolch erkennt nur Singleton Annotation und alle anderen Anmerkungen hat keine Auswirkungen auf Dolch Entscheidung, weil alle anderen Anmerkungen Umfang der Aktivität haben werden?

Antwort

1

so das Problem ist, dass Sie die ApplicationComponent der inject Methode

application.getApplicationComponent().inject(this); 

zuerst nennen, die alle Mitglieder zu injizieren versucht, die PermissionController einschließlich. Aber die ApplicationComponent kann das nicht bieten, und darüber beschwert sich Dagger.

Die Lösung besteht darin, nur die inject() - Methode der ActivityComponent aufzurufen.

Höchstwahrscheinlich benötigen Sie Abhängigkeiten, die von der ApplicationComponent zu einem bestimmten Zeitpunkt bereitgestellt werden. Um dies zu archivieren, müssten Sie die beiden Komponenten kombinieren.Dagger bietet zwei Möglichkeiten für das, subcomponents und component dependencies

Wenn Komponente Abhängigkeiten verwenden, rou mit so etwas wie dies enden würde in Ihrer Aktivität des onCreate() -Methode:

DaggerActivityComponent 
      .builder() 
      .applicationComponent(application.getApplicationComponent()) 
      .activityModule(new ActivityModule(this)) 
      .build().inject(this); 

, wenn Sie die Komponenten ändern etwas suchen ähnlich wie diese:

@PerActivity 
@Component(
    dependencies = ApplicationComponent.class, 
    modules = { 
     ActivityModule.class, 
     PermissionModule.class 
    } 
) 
public interface ActivityComponent { 
    ... 
} 

Notiz, die Sie benötigen Abhängigkeiten explizit in der ApplicationComponent zu liefern, wenn Sie es in der ActivityComponent (oder irgendwelchen Injektoren) benötigen

+0

Vielen Dank für die Antwort, nur etwas, das ich frage, ist es sauberer Weg, dies zu tun? Oder vielleicht gibt es eine andere Option? – dugdthndwytn

+0

Wie ich bereits erwähnt habe, können Sie dies auch mit Unterkomponenten tun. Aber anders als das Kombinieren des Abhängigkeitsgraphen und das Verwenden des Ergebnisses zum Auflösen von Abhängigkeiten glaube ich nicht, dass es eine sauberere Lösung gibt. Scoping ist auch nur sinnvoll, wenn Sie nur einen Objektgraphen haben. Andernfalls könnten Sie mehrere Instanzen für einen Bereich erhalten. – nosyjoe

0

Wenn eine Abhängigkeit von der übergeordneten Komponente besteht (z. B. @Componenet (model = AppModel.class) öffentliche Schnittstelle appComponent ...), die Sie in der untergeordneten Komponente verwenden möchten (@ActivityScope @Component (DEPENDENCY = APPCOMPONENT.class , model = ActivityModel.class) öffentliche Schnittstelle activityComponenet ...) Sie müssen es in der übergeordneten Komponente verfügbar machen. Nur exponierte Abhängigkeiten sind downstream verfügbar (in untergeordneten Komponenten). Sie tun dies, indem Sie eine Methode von appModel schreiben, die eine Abhängigkeit stromabwärts in der appComponenet-Schnittstelle bereitstellen muss. Der Name der Methode muss nicht mit dem Namen der Methode in appModel übereinstimmen, sondern nur mit der Anzahl der Rückgabetypen.