Search code examples
xamarin.androidviewmodel

Xamarin Android: how to implement a ViewModelProvider factory?


I'm trying to create a viewmodel provider factory and I'm little bit lost. I've already added the required Nuget packages and my view models extend the AndroidViewModel type. Now, I'd like to create a factory that would use autofac to create the required view models from the OnCreate activitie's method. The creation call looks like this:

_viewModel = (ViewModelProviders.Of(this, _viewModelFactory)
               .Get(Java.Lang.Class.FromType(typeof(MainActivityViewModel))) as JavaObjectWrapper<MainActivityViewModel>)
                .Object;

Now, the factory:

public class ViewModelFactory : ViewModelProvider.AndroidViewModelFactory {
    public ViewModelFactory(Application application) : base(application) {
    }

    public override Object Create(Class modelClass) {
        // TODO: any way to get the .NET type that was passed here?
        return base.Create(modelClass);
    }
}

Can I retrieve the .NET type (MainActivityViewModel) from the Class instance that is passed into the Create method call (the type would be required to resolve it from the autofac container)? If there is, how can I do that?

Thanks.


Solution

  • This is how I do this with Unity, but this pattern can be used for passing anything through the ViewModel constructor:

    The ViewModel itself

    public class HomeViewModel : ViewModel
    {
        IUnityContainer _unityContainer;
        public HomeViewModel(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }
    }
    

    The HomeViewModelFactory (Default constructor required)

    public class HomeViewModelFactory : Java.Lang.Object, ViewModelProvider.IFactory 
    {
        IUnityContainer _unityContainer;
    
        public HomeViewModelFactory()
        {
    
        }
    
        public HomeViewModelFactory(IUnityContainer unityContainer)
        {
            _unityContainer = unityContainer;
        }
    
        public Java.Lang.Object Create(Class p0)
        {
            return _unityContainer.Resolve<HomeViewModel>();
        }
    }
    

    Usage in Fragment

    public override void OnActivityCreated(Bundle savedInstanceState)
        {
            base.OnActivityCreated(savedInstanceState);
            var homeViewModelFactory = _unityContainer.Resolve<HomeViewModelFactory>();
            _homeViewModel = ViewModelProviders.Of(this, homeViewModelFactory).Get(Java.Lang.Class.FromType(typeof(HomeViewModel))) as HomeViewModel;
        }