ฉันพยายามพันหัวของฉันรอบขอบเขตใน Dagger 2 โดยเฉพาะวงจรชีวิตของกราฟที่กำหนดขอบเขต คุณจะสร้างส่วนประกอบที่จะล้างเมื่อคุณออกจากขอบเขตได้อย่างไร
ในกรณีของแอปพลิเคชัน Android โดยใช้ Dagger 1.x โดยทั่วไปคุณจะมีขอบเขตรูทที่ระดับแอปพลิเคชันซึ่งคุณจะขยายเพื่อสร้างขอบเขตย่อยในระดับกิจกรรม
public class MyActivity {
private ObjectGraph mGraph;
public void onCreate() {
mGraph = ((MyApp) getApplicationContext())
.getObjectGraph()
.plus(new ActivityModule())
.inject(this);
}
public void onDestroy() {
mGraph = null;
}
}
ขอบเขตย่อยมีอยู่ตราบเท่าที่คุณยังคงอ้างอิงอยู่ซึ่งในกรณีนี้คือวงจรชีวิตของกิจกรรมของคุณ การทิ้งข้อมูลอ้างอิงใน onDestroy ทำให้มั่นใจได้ว่ากราฟที่กำหนดขอบเขตนั้นไม่มีค่าใช้จ่ายในการเก็บขยะ
แก้ไข
Jesse Wilson เพิ่งโพสต์mea culpa
Dagger 1.0 ทำให้ชื่อขอบเขตของมันแย่ลง ... คำอธิบายประกอบ @Singleton ใช้สำหรับทั้งกราฟรูทและกราฟที่กำหนดเองดังนั้นจึงเป็นเรื่องยากที่จะเข้าใจว่าขอบเขตที่แท้จริงของสิ่งนั้นคืออะไร
และสิ่งอื่น ๆ ที่ฉันได้อ่าน / ได้ยินประเด็นเกี่ยวกับ Dagger 2 ในการปรับปรุงวิธีการทำงานของขอบเขต แต่ฉันกำลังพยายามที่จะเข้าใจความแตกต่าง ตามความคิดเห็นของ @Kirill Boyarshinov ด้านล่างวงจรชีวิตของส่วนประกอบหรือการพึ่งพายังคงถูกกำหนดตามปกติโดยการอ้างอิงที่เป็นรูปธรรม ดังนั้นความแตกต่างระหว่างขอบเขต Dagger 1.x และ 2.0 เป็นเรื่องของความชัดเจนทางความหมายหรือไม่?
ความเข้าใจของฉัน
กริช 1.x
การพึ่งพามี@Singleton
หรือไม่ นี่เป็นความจริงอย่างเท่าเทียมกันของการอ้างอิงในกราฟรูทและกราฟย่อยซึ่งนำไปสู่ความคลุมเครือว่ากราฟใดที่การอ้างอิงถูกผูกไว้ (ดูใน Dagger คือ Singletons ภายในกราฟย่อยที่แคชไว้หรือจะถูกสร้างขึ้นใหม่เสมอเมื่อมีกราฟย่อยกิจกรรมใหม่ ถูกสร้างขึ้น? )
กริช 2.0
ขอบเขตที่กำหนดเองช่วยให้คุณสามารถสร้างขอบเขตที่ชัดเจนในเชิงความหมาย แต่จะมีฟังก์ชันเทียบเท่ากับการใช้@Singleton
ใน Dagger 1.x
// Application level
@Singleton
@Component( modules = MyAppModule.class )
public interface MyAppComponent {
void inject(Application app);
}
@Module
public class MyAppModule {
@Singleton @Named("SingletonScope") @Provides
StringBuilder provideStringBuilderSingletonScope() {
return new StringBuilder("App");
}
}
// Our custom scope
@Scope public @interface PerActivity {}
// Activity level
@PerActivty
@Component(
dependencies = MyAppComponent.class,
modules = MyActivityModule.class
)
public interface MyActivityComponent {
void inject(Activity activity);
}
@Module
public class MyActivityModule {
@PerActivity @Named("ActivityScope") @Provides
StringBuilder provideStringBuilderActivityScope() {
return new StringBuilder("Activity");
}
@Name("Unscoped") @Provides
StringBuilder provideStringBuilderUnscoped() {
return new StringBuilder("Unscoped");
}
}
// Finally, a sample Activity which gets injected
public class MyActivity {
private MyActivityComponent component;
@Inject @Named("AppScope")
StringBuilder appScope
@Inject @Named("ActivityScope")
StringBuilder activityScope1
@Inject @Named("ActivityScope")
StringBuilder activityScope2
@Inject @Named("Unscoped")
StringBuilder unscoped1
@Inject @Named("Unscoped")
StringBuilder unscoped2
public void onCreate() {
component = Dagger_MyActivityComponent.builder()
.myApplicationComponent(App.getComponent())
.build()
.inject(this);
appScope.append(" > Activity")
appScope.build() // output matches "App (> Activity)+"
activityScope1.append("123")
activityScope1.build() // output: "Activity123"
activityScope2.append("456")
activityScope1.build() // output: "Activity123456"
unscoped1.append("123")
unscoped1.build() // output: "Unscoped123"
unscoped2.append("456")
unscoped2.build() // output: "Unscoped456"
}
public void onDestroy() {
component = null;
}
}
การนำกลับไปใช้เป็นการ@PerActivity
สื่อสารถึงความตั้งใจของคุณเกี่ยวกับวงจรชีวิตของส่วนประกอบนี้ แต่ท้ายที่สุดคุณสามารถใช้ส่วนประกอบได้ทุกที่ทุกเวลา คำสัญญาเดียวของ Dagger คือสำหรับส่วนประกอบที่กำหนดวิธีการที่มีคำอธิบายประกอบขอบเขตจะส่งคืนอินสแตนซ์เดียว ฉันยังถือว่า Dagger 2 ใช้คำอธิบายประกอบขอบเขตบนส่วนประกอบเพื่อตรวจสอบว่าโมดูลให้การอ้างอิงที่อยู่ในขอบเขตเดียวกันหรือไม่ใช่ขอบเขตเท่านั้น
สรุป
การพึ่งพายังคงเป็นแบบซิงเกิลตันหรือไม่ใช่ซิงเกิลตัน แต่@Singleton
ตอนนี้มีไว้สำหรับอินสแตนซ์ซิงเกิลระดับแอปพลิเคชันและขอบเขตที่กำหนดเองเป็นวิธีที่ต้องการสำหรับการใส่คำอธิบายประกอบการอ้างอิงซิงเกิลตันที่มีวงจรชีวิตสั้นลง
นักพัฒนามีหน้าที่จัดการวงจรชีวิตของส่วนประกอบ / การอ้างอิงโดยทิ้งการอ้างอิงที่ไม่จำเป็นอีกต่อไปและรับผิดชอบในการตรวจสอบให้แน่ใจว่าส่วนประกอบถูกสร้างขึ้นเพียงครั้งเดียวในขอบเขตที่ต้องการ แต่คำอธิบายประกอบขอบเขตที่กำหนดเองทำให้ง่ายต่อการระบุขอบเขตนั้น .
คำถาม $ 64,000 *
ความเข้าใจของฉันเกี่ยวกับขอบเขตและวงจรชีวิตของ Dagger 2 ถูกต้องหรือไม่?
* ไม่ใช่คำถาม 64,000 เหรียญ
plus()
การอ้างอิงไปยังกราฟใหม่ถูกเก็บไว้ใน Activity และถูกผูกไว้กับ livecycle (dereferenced inonDestroy
) สำหรับขอบเขตจะช่วยให้มั่นใจได้ว่าการติดตั้งส่วนประกอบของคุณจะถูกสร้างขึ้นโดยไม่มีข้อผิดพลาดในเวลาคอมไพล์โดยมีการพึ่งพาทุกครั้ง ดังนั้นจึงไม่ใช่แค่เพื่อวัตถุประสงค์ในการจัดทำเอกสารเท่านั้น ดูตัวอย่างจากหัวข้อนี้