简体   繁体   中英

How to register ViewModel with constructor injection in LightMvvm Xamarin.Forms?

As is written in title, i have problem with my MvvmLight app under Xamarin.Forms. I have such code for my exemplary ViewModel.

public interface IMainViewModel
{

}

public class MainViewModel : ViewModelBase, IMainViewModel
{
    private readonly IDataService<Todoo> _dataService;
    private readonly INavigationService _navigationService;

    public MainViewModel(IDataService<Todoo> dataService, INavigationService navigationService)
    {
        if (navigationService == null)
            throw new ArgumentNullException(nameof(navigationService), "Navigation service cannot be null");
        _navigationService = navigationService;

        if (dataService == null)
            throw new ArgumentNullException(nameof(dataService), "Data service cannot be null");
        _dataService = dataService;

        NavigationCommand = new RelayCommand<string>(parameter => Navigate(parameter));
    }

    private void Navigate(string parameter)
    {
        // _navigationService.NavigateTo(ViewModelLocator.MainPage, parameter ?? string.Empty);
        _navigationService.NavigateTo(ViewModelLocator.AddNewTodooPage);
    }

    public RelayCommand<string> NavigationCommand { get; private set; }
}

This is an ViewModelLocator

public class ViewModelLocator
{
    public const string MainPage = "MainPage";
    public const string AddNewTodooPage = "AddNewTodooPage";

    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<IMainViewModel, MainViewModel>();
        SimpleIoc.Default.Register<IAddNewTodooViewModel, AddNewTodooViewModel>();
    }

    public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
    public AddNewTodooViewModel AddNewTodoo => ServiceLocator.Current.GetInstance<AddNewTodooViewModel>();

    public static void Cleanup()
    {
        // TODO Clear the ViewModels
    }
}

And App.cs

public partial class App
{
    private static ViewModelLocator _locator;

    public static ViewModelLocator Locator => _locator ?? (_locator = new ViewModelLocator());

    public App()
    {
        SimpleIoc.Default.Register<IDataService<Todoo>>(() => new TodoosDataService());
        SimpleIoc.Default.Register<IRepository<Todoo>>(() => new FakeTodoosRepository());

        var nav = new NavigationService();

        nav.Configure(ViewModelLocator.MainPage, typeof(MainPage));
        nav.Configure(ViewModelLocator.AddNewTodooPage, typeof(AddNewTodooPage));

        SimpleIoc.Default.Register<INavigationService>(() => nav);

        var mainPage = new NavigationPage(new MainPage());

        nav.Initialize(mainPage);

        MainPage = mainPage;
    }

    public static Page GetMainPage()
    {
        return new MainPage();
    }

    public static Page GetAddNewTodooPage()
    {
        return new AddNewTodooPage();
    }
}

What is wrong here with registration my ViewModel that it cannot resolve injected objects? When i run this code it fails, it work when I add parameterless constructor, so I assume that ViewModel is not created properly in terms of constructor injection.

If there is lack of some crucial code please let me know, i will post it.

T.Hanks in advance for any feedback.

I just resolved this. I was doing almost everything wrong but now it is working well. If anybody is interested how this should look properly (I guess..) I could post working code for this issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM