নির্ভরতা সহ ভিউ মডেল তৈরি করুন অ্যান্ড্রয়েড জেটপ্যাকের অংশ।

নির্ভরতা ইনজেকশনের সর্বোত্তম অনুশীলন অনুসরণ করে, ViewModels তাদের কনস্ট্রাক্টরে পরামিতি হিসাবে নির্ভরতা নিতে পারে। এগুলি বেশিরভাগই ডোমেন বা ডেটা স্তরের প্রকারের। যেহেতু ফ্রেমওয়ার্ক ভিউমডেলগুলি সরবরাহ করে, সেগুলির উদাহরণ তৈরি করার জন্য একটি বিশেষ প্রক্রিয়া প্রয়োজন৷ সেই মেকানিজম হল ViewModelProvider.Factory ইন্টারফেস। শুধুমাত্র এই ইন্টারফেসের বাস্তবায়নই সঠিক সুযোগে ViewModelsকে ইনস্ট্যান্টিয়েট করতে পারে

CreationExtras সহ মডেলগুলি দেখুন

যদি একটি ViewModel ক্লাস তার কনস্ট্রাক্টরে নির্ভরতা পায়, তাহলে একটি ফ্যাক্টরি প্রদান করুন যা ViewModelProvider.Factory ইন্টারফেস প্রয়োগ করে। ViewModel-এর একটি নতুন উদাহরণ প্রদান করতে create(Class<T>, CreationExtras) ফাংশনটিকে ওভাররাইড করুন।

CreationExtras আপনাকে প্রাসঙ্গিক তথ্য অ্যাক্সেস করতে দেয় যা একটি ViewModelকে তাৎক্ষণিকভাবে সাহায্য করে। এখানে কীগুলির একটি তালিকা রয়েছে যা অতিরিক্ত থেকে অ্যাক্সেস করা যেতে পারে:

চাবি কার্যকারিতা
ViewModelProvider.NewInstanceFactory.VIEW_MODEL_KEY আপনি ViewModelProvider.get() এ পাস করা কাস্টম কীটিতে অ্যাক্সেস প্রদান করে।
ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY Application ক্লাসের উদাহরণে অ্যাক্সেস প্রদান করে।
SavedStateHandleSupport.DEFAULT_ARGS_KEY SavedStateHandle তৈরি করতে আপনার যে আর্গুমেন্টগুলি ব্যবহার করা উচিত তার বান্ডিল অ্যাক্সেস প্রদান করে।
SavedStateHandleSupport.SAVED_STATE_REGISTRY_OWNER_KEY SavedStateRegistryOwner এ অ্যাক্সেস প্রদান করে যা ViewModel তৈরি করতে ব্যবহার করা হচ্ছে।
SavedStateHandleSupport.VIEW_MODEL_STORE_OWNER_KEY ViewModelStoreOwner এ অ্যাক্সেস প্রদান করে যা ViewModel নির্মাণ করতে ব্যবহৃত হচ্ছে।

SavedStateHandle এর একটি নতুন উদাহরণ তৈরি করতে, CreationExtras.createSavedStateHandle() ফাংশনটি ব্যবহার করুন এবং এটি ViewModel-এ পাস করুন।

APPLICATION_KEY এর সাথে অতিরিক্ত সৃষ্টি

একটি ViewModel একটি উদাহরণ কীভাবে প্রদান করা যায় তার একটি উদাহরণ নিচে দেওয়া হল যা Application ক্লাসে একটি সংগ্রহস্থল এবং SavedStateHandle নির্ভরতা হিসাবে গ্রহণ করে:

কোটলিন

    import androidx.lifecycle.SavedStateHandle
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.ViewModelProvider
    import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
    import androidx.lifecycle.createSavedStateHandle
    import androidx.lifecycle.viewmodel.CreationExtras

    class MyViewModel(
        private val myRepository: MyRepository,
        private val savedStateHandle: SavedStateHandle
    ) : ViewModel() {

        // ViewModel logic
        // ...

        // Define ViewModel factory in a companion object
        companion object {

            val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
                @Suppress("UNCHECKED_CAST")
                override fun <T : ViewModel> create(
                    modelClass: Class<T>,
                    extras: CreationExtras
                ): T {
                    // Get the Application object from extras
                    val application = checkNotNull(extras[APPLICATION_KEY])
                    // Create a SavedStateHandle for this ViewModel from extras
                    val savedStateHandle = extras.createSavedStateHandle()

                    return MyViewModel(
                        (application as MyApplication).myRepository,
                        savedStateHandle
                    ) as T
                }
            }
        }
    }

জাভা

import static androidx.lifecycle.SavedStateHandleSupport.createSavedStateHandle;
import static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY;

import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.viewmodel.ViewModelInitializer;

public class MyViewModel extends ViewModel {

    public MyViewModel(
        MyRepository myRepository,
        SavedStateHandle savedStateHandle
    ) { /* Init ViewModel here */ }

    static final ViewModelInitializer<MyViewModel> initializer = new ViewModelInitializer<>(
        MyViewModel.class,
        creationExtras -> {
            MyApplication app = (MyApplication) creationExtras.get(APPLICATION_KEY);
            assert app != null;
            SavedStateHandle savedStateHandle = createSavedStateHandle(creationExtras);

            return new MyViewModel(app.getMyRepository(), savedStateHandle);
        }
    );
}

তারপর, ViewModel এর একটি উদাহরণ পুনরুদ্ধার করার সময় আপনি এই কারখানাটি ব্যবহার করতে পারেন:

কোটলিন

import androidx.activity.viewModels

class MyActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels { MyViewModel.Factory }

    // Rest of Activity code
}

জাভা

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

public class MyActivity extends AppCompatActivity {

MyViewModel myViewModel = new ViewModelProvider(
    this,
    ViewModelProvider.Factory.from(MyViewModel.initializer)
).get(MyViewModel.class);

// Rest of Activity code
}

জেটপ্যাক রচনা

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun MyScreen(
    modifier: Modifier = Modifier,
    viewModel: MyViewModel = viewModel(factory = MyViewModel.Factory)
) {
    // ...
}

বিকল্পভাবে, আরও মূর্তিপূর্ণ Kotlin API ব্যবহার করে কারখানা তৈরি করতে ViewModel কারখানা DSL ব্যবহার করুন:

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory

class MyViewModel(
    private val myRepository: MyRepository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    // ViewModel logic

    // Define ViewModel factory in a companion object
    companion object {
        val Factory: ViewModelProvider.Factory = viewModelFactory {
            initializer {
                val savedStateHandle = createSavedStateHandle()
                val myRepository = (this[APPLICATION_KEY] as MyApplication).myRepository
                MyViewModel(
                    myRepository = myRepository,
                    savedStateHandle = savedStateHandle
                )
            }
        }
    }
}

CreationExtras হিসাবে কাস্টম প্যারামিটার পাস করুন

আপনি একটি কাস্টম কী তৈরি করে CreationExtras মাধ্যমে আপনার ViewModel এ নির্ভরতা পাস করতে পারেন। এটি উপযোগী হতে পারে যদি আপনার ViewModel এমন বস্তুর উপর নির্ভর করে যা Application ক্লাস এবং APPLICATION_KEY মাধ্যমে অ্যাক্সেসযোগ্য নয়। এটির একটি উদাহরণ হল যখন আপনার ViewModel একটি Kotlin Multiplatform মডিউলের মধ্যে তৈরি করা হয় এবং সেইজন্য Android নির্ভরতায় অ্যাক্সেস থাকে না।

এই উদাহরণে, ViewModel একটি কাস্টম কী সংজ্ঞায়িত করে এবং এটি ViewModelProvider.Factory এ ব্যবহার করে।

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory

class MyViewModel(
    private val myRepository: MyRepository,
) : ViewModel() {
    // ViewModel logic

    // Define ViewModel factory in a companion object
    companion object {

        // Define a custom key for your dependency
        val MY_REPOSITORY_KEY = object : CreationExtras.Key<MyRepository> {}

        val Factory: ViewModelProvider.Factory = viewModelFactory {
            initializer {
                // Get the dependency in your factory
                val myRepository = this[MY_REPOSITORY_KEY] as MyRepository
                MyViewModel(
                    myRepository = myRepository,
                )
            }
        }
    }
}

আপনি একটি ViewModelStoreOwner যেমন ComponentActivity , Fragment , বা NavBackStackEntry , অথবা Jetpack রচনার মাধ্যমে একটি CreationExtras.Key সহ একটি ViewModel ইনস্ট্যান্ট করতে পারেন৷

কোটলিন

import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.CreationExtras
import androidx.lifecycle.viewmodel.MutableCreationExtras
// ...
    // Use from ComponentActivity, Fragment, NavBackStackEntry,
    // or another ViewModelStoreOwner.
    val viewModelStoreOwner: ViewModelStoreOwner = this
    val myViewModel: MyViewModel = ViewModelProvider.create(
        viewModelStoreOwner,
        factory = MyViewModel.Factory,
        extras = MutableCreationExtras().apply {
            set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
        },
    )[MyViewModel::class]

জেটপ্যাক রচনা

import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.compose.viewModel
// ...
@Composable
fun MyApp(myRepository: MyRepository) {
    val extras = MutableCreationExtras().apply {
        set(MyViewModel.MY_REPOSITORY_KEY, myRepository)
    }
    val viewModel: MyViewModel = viewModel(
        factory = MyViewModel.Factory,
        extras = extras,
    )
}

2.5.0 এর থেকে পুরানো ViewModel সংস্করণের জন্য কারখানা

আপনি যদি ViewModel এর 2.5.0-এর চেয়ে পুরানো সংস্করণ ব্যবহার করেন, তাহলে আপনাকে ViewModelProvider.Factory প্রসারিত করে এমন একটি ক্লাসের উপসেট থেকে কারখানাগুলি সরবরাহ করতে হবে এবং create(Class<T>) ফাংশনটি বাস্তবায়ন করতে হবে। ViewModel কী নির্ভরতা প্রয়োজন তার উপর নির্ভর করে, একটি ভিন্ন শ্রেণী থেকে প্রসারিত করা দরকার:

Application বা SavedStateHandle প্রয়োজন না হলে, কেবল ViewModelProvider.Factory থেকে প্রসারিত করুন।

নিম্নলিখিত উদাহরণটি একটি ভিউমডেলের জন্য একটি AbstractSavedStateViewModelFactory ব্যবহার করে যা নির্ভরতা হিসাবে একটি সংগ্রহস্থল এবং একটি SavedStateHandle প্রকার নেয়:

কোটলিন

class MyViewModel(
private val myRepository: MyRepository,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {

// ViewModel logic ...

// Define ViewModel factory in a companion object
companion object {
    fun provideFactory(
        myRepository: MyRepository,
        owner: SavedStateRegistryOwner,
        defaultArgs: Bundle? = null,
    ): AbstractSavedStateViewModelFactory =
        object : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(
                key: String,
                modelClass: Class<T>,
                handle: SavedStateHandle
            ): T {
                return MyViewModel(myRepository, handle) as T
            }
        }
    }
}

জাভা

import androidx.annotation.NonNull;
import androidx.lifecycle.AbstractSavedStateViewModelFactory;
import androidx.lifecycle.SavedStateHandle;
import androidx.lifecycle.ViewModel;

public class MyViewModel extends ViewModel {
    public MyViewModel(
        MyRepository myRepository,
        SavedStateHandle savedStateHandle
    ) { /* Init ViewModel here */ }
}

public class MyViewModelFactory extends AbstractSavedStateViewModelFactory {

    private final MyRepository myRepository;

    public MyViewModelFactory(
        MyRepository myRepository
    ) {
        this.myRepository = myRepository;
    }

    @SuppressWarnings("unchecked")
    @NonNull
    @Override
    protected <T extends ViewModel> T create(
        @NonNull String key, @NonNull Class<T> modelClass, @NonNull SavedStateHandle handle
    ) {
        return (T) new MyViewModel(myRepository, handle);
    }
}

তারপর, আপনি আপনার ViewModel পুনরুদ্ধার করতে কারখানা ব্যবহার করতে পারেন:

কোটলিন

import androidx.activity.viewModels

class MyActivity : AppCompatActivity() {

    private val viewModel: MyViewModel by viewModels {
        MyViewModel.provideFactory((application as MyApplication).myRepository, this)
    }

    // Rest of Activity code
}

জাভা

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;

public class MyActivity extends AppCompatActivity {

    MyViewModel myViewModel = new ViewModelProvider(
        this,
        ViewModelProvider.Factory.from(MyViewModel.initializer)
    ).get(MyViewModel.class);

    // Rest of Activity code
}

জেটপ্যাক রচনা

import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun MyScreen(
    modifier: Modifier = Modifier,
    viewModel: MyViewModel = viewModel(
        factory = MyViewModel.provideFactory(
            (LocalContext.current.applicationContext as MyApplication).myRepository,
            owner = LocalSavedStateRegistryOwner.current
        )
    )
) {
    // ...
}
{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}