2014-11-06 2 views
0

Я хочу заменить наш компонентный реестр (с помощью магии загрузчика класса dexfile) с инфраструктурой инъекций зависимостей для Android. Первая попытка - кинжал.Dagger 1.x @Inject бросает IllegalArgumentException

При попытке я получаю следующее сообщение об ошибке:

11-06 13:05:41.040 16269-16269/com.daggertoolkitexample E/AndroidRuntime﹕ FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity ComponentInfo{daggertoolkitexample/com.dagger.MyActivity}: java.lang.IllegalArgumentException: No inject registered for members/com.dagger.MyActivity. You must explicitly add it to the 'injects' option in one of your modules. 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295) 
     ... 
Caused by: java.lang.IllegalArgumentException: No inject registered for members/com.dagger.MyActivity. You must explicitly add it to the 'injects' option in one of your modules. 
     at dagger.ObjectGraph$DaggerObjectGraph.getInjectableTypeBinding(ObjectGraph.java:302) 
     at dagger.ObjectGraph$DaggerObjectGraph.inject(ObjectGraph.java:279) 
     at com.dagger.MyApplication.inject(MyApplication.java:39) 
     at com.dagger.MyBaseActivity.onCreate(MyBaseActivity.java:18) 
     at com.dagger.MyActivity.onCreate(MyActivity.java:22) 
     at android.app.Activity.performCreate(Activity.java:5372) 
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104) 
     ... 

я могу это исправить, если я впрыснуть свою деятельность в @Module. Его работа без исключения.

@Module(
    library = true, 
    injects = MyActivity.class) 
public class AuthManagementModul {...}` 

Но это не то, что я хочу. Я не могу и хочу знать всех пользователей моего компонента.

Есть ли у всех идеи, что не так?

Вот мой пример кода:

public class MyBaseActivity extends ActionBarActivity { 

    @Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ((MyApplication) getApplication()).inject(this); 
    } 
} 

...

public class MyActivity extends MyBaseActivity { 

    @Inject AuthManagement authManagement; 

    ... 
} 

...

public class MyApplication extends Application{ 

    private ObjectGraph graph; 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    graph = ObjectGraph.create(new AuthManagementModul(this)); 
    } 

    public void inject(Object object) { 
    graph.inject(object); 
    } 
} 

...

@Module(
    library = true 
) 
public class AuthManagementModul { 

    private final Application application; 

    public AuthManagementModul(Application application) { 
    this.application = application; 
    } 

    @Provides 
    @Singleton 
    AuthManagement provideAuthManagement() { 
    return new AuthManagementImpl(application); 
} 
} 

ответ

0

В этом случае вы не хотите добавлять adds = в свой AuthManagementModul, а скорее к модулю, соответствующему действию, который включает его.

Dagger 1.x использует injects = как сигнал для того, какие анализируемые граф-корни должны присутствовать, но они не должны присутствовать в библиотечных модулях листовых узлов - только на модуле, который использует деятельность. Рассмотрим разбивая свои модули на более секционированных линий так:

@Module(
    injects = { 
    ... all your activities 
    }, 
    includes = { 
    AuthManagementModul.class, 
    ApplicationModule.class 
    } 
) 
class EntryPointsModule {} 

@Module(library = true, complete = false) 
class AuthManagementModul { 
    @Provides 
    @Singleton 
    AuthManagement provideAuthManagement(Application application) { 
    return new AuthManagementImpl(application); 
    } 
} 

@Module(library = true)  
class ApplicationModule { 

    private final Application application; 

    public ApplicationModule(Application application) { 
    this.application = application; 
    } 

    @Provides 
    @Singleton 
    Application application() { 
    return application; 
    } 
} 

Затем создайте свой график так:

public class MyApplication extends Application{ 

    private ObjectGraph graph; 

    @Override 
    public void onCreate() { 
    super.onCreate(); 
    // AuthManagementModul is automatically included because it has a default 
    // constructor and is included by EntryPointsModule 
    graph = ObjectGraph.create(new EntryPointsModule(), new ApplicationModule(this)); 
    } 

    public void inject(Object object) { 
    graph.inject(object); 
    } 
} 

Есть другие способы структурирования этого - вы можете просто ApplicationModule включают AuthModule и объявлять инъекции, поэтому у вас есть только два модуля и т. д. Я предложил этот способ, потому что ApplicationModule - это отдельная проблема, единственная роль которой заключается в том, чтобы поднять экземпляр приложения в граф, AuthManagementModul предназначен исключительно для поддержки функции auth, а EntryPointsModule быть фронтом всего графика.

Если вы перейдете на Dagger2, эта структура также удобна в том, что EntryPointsModule естественно преобразуется в @Component.

+0

спасибо! – Marko

Смежные вопросы