ডাগর 2-তে কোন উপাদানটির উপাদান (গ্রাফ) এর জীবনচক্র নির্ধারণ করে?


134

আমি ডাগার 2-এ স্কোপগুলি ঘিরে আমার মাথা মোড়ানোর চেষ্টা করছি, বিশেষত স্কোপযুক্ত গ্রাফগুলির জীবনকাল cle আপনি কীভাবে এমন একটি উপাদান তৈরি করবেন যা আপনি সুযোগ ছেড়ে দিলে পরিষ্কার হয়ে যাবে।

অ্যান্ড্রয়েড অ্যাপ্লিকেশনের ক্ষেত্রে, ডাগার ১.x ব্যবহার করে আপনার সাধারণত অ্যাপ্লিকেশন স্তরে মূল সুযোগ থাকে যা আপনি ক্রিয়াকলাপ স্তরে শিশু সুযোগ তৈরি করতে প্রসারিত করতে চান।

public class MyActivity {

    private ObjectGraph mGraph;

    public void onCreate() {
        mGraph = ((MyApp) getApplicationContext())
            .getObjectGraph()
            .plus(new ActivityModule())
            .inject(this);
    }

    public void onDestroy() {
        mGraph = null;
    }
}

সন্তানের সুযোগটি যতক্ষণ আপনি এটির জন্য একটি রেফারেন্স রেখেছিলেন অস্তিত্ব ছিল, যা এই ক্ষেত্রে আপনার ক্রিয়াকলাপের জীবনচক্র। অনডাস্ট্রয়েতে রেফারেন্সটি ফেলে দেওয়া নিশ্চিত করেছে যে স্কোপড গ্রাফটি আবর্জনা সংগ্রহের জন্য মুক্ত ছিল।

সম্পাদনা

জেসি উইলসন সম্প্রতি একটি মেয়া কুলপা পোস্ট করেছেন

ডাগার ১.০ এর স্কোপের নামগুলি খারাপভাবে চিহ্নিত করেছে ... @ সিঙ্গেলটন টীকাগুলি মূল গ্রাফ এবং কাস্টম গ্রাফ উভয়ের জন্যই ব্যবহৃত হয়, সুতরাং কোনও জিনিসের আসল সুযোগ কী তা নির্ধারণ করা খুব মুশকিল।

এবং আমি ডাগার 2 এর দিকে পয়েন্টগুলি পড়ে / শুনেছি এমন সমস্ত বিষয় যা স্কোপগুলি কাজ করে তার উন্নতি করে তবে আমি পার্থক্যটি বোঝার জন্য সংগ্রাম করছি। নীচে @ কিরিল বোয়ারশিনভের মন্তব্য অনুসারে, কোনও উপাদান বা নির্ভরতার জীবনকালটি এখনও যথারীতি, কংক্রিটের উল্লেখ দ্বারা নির্ধারিত হয়। তাহলে ডাগার ১.x এবং ২.০ স্কোপের মধ্যে পার্থক্যটি কি নির্ভুলভাবে অর্থগত স্পষ্টতার বিষয়?

আমার বোঝাপড়া

ছিনতাইকারী 1.x

নির্ভরতা ছিল @Singletonনা হয়। এটি মূল গ্রাফ এবং সাবগ্রাফের উপর নির্ভরশীলতার ক্ষেত্রেও সমানভাবে সত্য ছিল, যা গ্রাফের উপর নির্ভরশীলতা আবদ্ধ ছিল তা অস্পষ্টতার দিকে নিয়ে যায় (দেখুন ড্যাজারটিতে সাব-গ্রাফের ক্যাশেডের মধ্যে সিঙ্গেলন রয়েছে বা কোনও নতুন ক্রিয়াকলাপের উপ-গ্রাফের সময় সেগুলি পুনরায় তৈরি করা হবে) নির্মিত হয়? )

ডাগার ২.০

কাস্টম স্কোপগুলি আপনাকে শব্দার্থগতভাবে পরিষ্কার স্কোপগুলি তৈরি করতে দেয় তবে @Singletonডাগার 1.x এ প্রয়োগ করার মতো এটি কার্যত সমতুল্য are

// 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আপনার অভিপ্রায়টি প্রকাশিত হয় তবে শেষ পর্যন্ত আপনি যে কোনও জায়গায় / যে কোনও সময় উপাদানটি ব্যবহার করতে পারেন। ড্যাজারের একমাত্র প্রতিশ্রুতিটি হল যে কোনও প্রদত্ত উপাদানটির জন্য স্কোপ এনোটোটেড পদ্ধতিগুলি একটি একক দৃষ্টিকোন ফিরে আসবে। আমি ধরেই নিয়েছি ডাগর 2 উপাদানটির স্কোপ এনোটোটেশনটি ব্যবহার করে যাচাই করতে মডিউলগুলি কেবল একই সুযোগে বা স্কোপযুক্ত নয় এমন নির্ভরশীলতা সরবরাহ করে।

সংক্ষেপে

নির্ভরতা এখনও সিঙ্গলটন বা নন-সিঙ্গলটন, তবে @Singletonএখন অ্যাপ্লিকেশন-স্তরের সিঙ্গেলটন দৃষ্টান্তের জন্য তৈরি এবং কাস্টম স্কোপগুলি একটি সংক্ষিপ্ত লাইফসাইকেলের সাথে সিঙ্গেলটন নির্ভরতাগুলি বর্নিত করার জন্য পছন্দসই পদ্ধতি।

বিকাশকারীগুলি প্রয়োজনীয় রেফারেন্সগুলি ফেলে রাখার মাধ্যমে উপাদানগুলি / নির্ভরতাগুলির আজীবন পরিচালনার জন্য দায়বদ্ধ যে উপাদানগুলি কেবল তাদের উদ্দেশ্যে তৈরি করা হয়েছে এমন সুযোগে কেবল একবার তৈরি হয়েছিল তা নিশ্চিত করার জন্য, তবে কাস্টম স্কোপ টিকাশীকরণগুলি সেই সুযোগটি সনাক্ত করা সহজ করে তোলে ।

$ 64k প্রশ্ন *

ডাগার 2 স্কোপ এবং লাইফসাইকেলের সম্পর্কে আমার বোঝাটি কি সঠিক?

* আসলে $ 64'000 প্রশ্ন নয়।


5
আপনি কিছুই মিস করেন নি। প্রতিটি উপাদান লাইভসাইকে পরিচালনা করা ম্যানুয়াল। আমার নিজের অভিজ্ঞতা থেকে ডাগার 1 এও ছিল in অ্যাপ্লিকেশন স্তরের সাবগ্রাফিটিংয়ের সময় plus()নতুন গ্রাফের রেফারেন্স ব্যবহার করে অবজেক্টগ্রাফ অবজেক্টটি ক্রিয়াকলাপে সংরক্ষণ করা হয়েছিল এবং এটির লাইভসাইকেলের সাথে আবদ্ধ ছিল (এতে নির্ধারিত হয়েছে onDestroy)। স্কোপ হিসাবে, তারা নিশ্চিত করে যে প্রতিটি উপাদান নির্ভরতা সন্তুষ্ট সহ সংকলন সময়ে ত্রুটি ছাড়াই আপনার উপাদান প্রয়োগগুলি উত্পন্ন হয়েছে। সুতরাং এটি কেবল নথিপত্রের উদ্দেশ্যে নয় for এই থ্রেড থেকে কিছু উদাহরণ দেখুন ।
কিরিল বোয়ারশিভিনভ

1
এই বিষয়ে কেবল পরিষ্কার করে বলতে গেলে, "আনস্কোপড" সরবরাহকারী পদ্ধতিগুলি প্রতিটি ইনজেকশনে নতুন দৃষ্টান্ত ফেরত দেয়?
ব্যবহারকারী 1923613

2
আপনি কেন উপাদান নির্ধারণ করেন = নাল; onDestroy () এ?
মারিয়ান পাডজিওচ

উত্তর:


70

আপনার প্রশ্ন হিসাবে

ডাগর 2-তে কোন উপাদানটির উপাদান (গ্রাফ) এর জীবনচক্র নির্ধারণ করে?

সংক্ষিপ্ত উত্তর আপনি এটি নির্ধারণ করা হয় । আপনার উপাদান যেমন একটি সুযোগ দেওয়া যেতে পারে

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationScope {
}

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

এগুলি দুটি কাজের জন্য আপনার জন্য দরকারী:

  • সুযোগের বৈধতা: কোনও উপাদানটিতে কেবল আপনার উপাদান হিসাবে একই স্কোপযুক্ত অপ্রকাশিত সরবরাহকারী বা স্কোপড সরবরাহকারী থাকতে পারে।

@Component(modules={ApplicationModule.class})
@ApplicationScope
public interface ApplicationComponent {
    Something something();
    AnotherThing anotherThing();

    void inject(Whatever whatever);
}

@Module
public class ApplicationModule {
    @ApplicationScope //application-scoped provider, only one can exist per component
    @Provides
    public Something something() {
         return new Something();
    }

    @Provides //unscoped, each INJECT call creates a new instance
    public AnotherThing anotherThing() {
        return new AnotherThing();
    }
}
  • আপনার স্কোপযুক্ত নির্ভরতা সাব-স্কোপিংয়ের অনুমতি দেয়, এভাবে আপনাকে একটি "সাবস্কোপড" উপাদান তৈরি করতে দেয় যা "সুপারসকপড" উপাদান থেকে সরবরাহিত দৃষ্টান্তগুলি ব্যবহার করে।

এটি @Subcomponentটিকা, বা উপাদান নির্ভরতা সহ করা যেতে পারে । আমি ব্যক্তিগতভাবে নির্ভরতা পছন্দ করি।

@Component(modules={ApplicationModule.class})
@ApplicationScope
public interface ApplicationComponent {
    Something something();
    AnotherThing anotherThing();

    void inject(Whatever whatever);

    ActivityComponent newActivityComponent(ActivityModule activityModule); //subcomponent factory method
}

@Subcomponent(modules={ActivityModule.class})
@ActivityScope
public interface ActivityComponent {
    ThirdThingy thirdThingy();

    void inject(SomeActivity someActivity);
}

@Module
public class ActivityModule {
    private Activity activity;

    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    //...
}

ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
ActivityComponent activityComponent = applicationComponent.newActivityComponent(new ActivityModule(SomeActivity.this));

অথবা আপনি যেমন উপাদান নির্ভরতা ব্যবহার করতে পারেন

@Component(modules={ApplicationModule.class})
@ApplicationScope
public class ApplicationComponent {
    Something something(); 
    AnotherThing anotherThing();

    void inject(Whatever whatever);
}

@Component(dependencies={ApplicationComponent.class}, modules={ActivityModule.class})
@ActivityScope
public interface ActivityComponent extends ApplicationComponent {
    ThirdThingy thirdThingy();

    void inject(SomeActivity someActivity);
}

@Module
public class ActivityModule {
    private Activity activity;

    public ActivityModule(Activity activity) {
        this.activity = activity;
    }

    //...
}

ApplicationComponent applicationComponent = DaggerApplicationComponent.create();
ActivityComponent activityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(SomeActivity.this)).build();

জেনে রাখা গুরুত্বপূর্ণ বিষয়:

  • একটি স্কোপযুক্ত সরবরাহকারী প্রতিটি উপাদানগুলির জন্য প্রদত্ত সুযোগের জন্য একটি উদাহরণ তৈরি করে । অর্থ একটি উপাদান তার নিজস্ব দৃষ্টিতে নজর রাখে, তবে অন্যান্য উপাদানগুলির একটি ভাগ করা স্কোপ পুল বা কিছু জাদু নেই। প্রদত্ত সুযোগে একটি উদাহরণ থাকার জন্য, আপনাকে উপাদানটির একটি উদাহরণ প্রয়োজন। এজন্য আপনাকে অবশ্যই ApplicationComponentতার নিজস্ব স্কোপযুক্ত নির্ভরতা অ্যাক্সেসের জন্য সরবরাহ করতে হবে ।

  • একটি উপাদান কেবল একটি স্কোপযুক্ত উপাদানকে সাবস্কোপ করতে পারে। একাধিক স্কোপযুক্ত উপাদান নির্ভরতা অনুমোদিত নয়।


একটি উপাদান কেবল একটি স্কোপযুক্ত উপাদানকে সাবস্কোপ করতে পারে। একাধিক স্কোপযুক্ত উপাদান নির্ভরতা মঞ্জুরিপ্রাপ্ত নয় (তাদের সকলের আলাদা আলাদা স্কোপ থাকলেও নয়, যদিও আমি মনে করি এটি একটি বাগ) g আসলে এর অর্থ কী তা বুঝতে পারছি না
ড্যামন ইউয়ান

লাইভসাইকেলের কথা কি? ক্রিয়াকলাপটি ধ্বংস হয়ে গেলে আবর্জনা সংগ্রাহকের জন্য ক্রিয়াকলাপের প্রার্থী প্রার্থী হবেন?
বিভক্ত

আপনি যদি এটি অন্য কোথাও না সঞ্চয় করেন তবে হ্যাঁ
এপিকপান্ডাফোর

1
সুতরাং যদি আমাদের ক্রিয়াকলাপের মাধ্যমে উপাদান এবং ইনজেকশনযুক্ত বস্তুর লাইভ প্রয়োজন হয় তবে আমরা ক্রিয়াকলাপের মধ্যে উপাদান তৈরি করি। আমরা যদি কেবলমাত্র একটি খন্ডের মধ্য দিয়ে টিকে থাকতে চাই তবে আমার খণ্ডের ভিতরে উপাদান তৈরি করা উচিত, তাই না? আপনি উপাদান রাখুন যেখানে সুযোগ তৈরি করে?
থ্রেসিয়ান

আমি যদি কোনও নির্দিষ্ট ক্রিয়াকলাপের মাধ্যমে বেঁচে থাকতে চাই তবে আমার কী করা উচিত?
থ্রেসিয়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.