1
\$\begingroup\$

I am new to Xamarin Forms and I have been searching online finding ways to set up navigation in a MVVM fashion. In particular I am designing around a concept I found here. However, I am using Ninject to have a ViewModelLocator type object in my application.

Here is the code to my Locator object:

public class Locator
{
    private readonly IKernel _kernel;

    public const string MainPage = "MainPage";
    public const string AlertPage = "AlertPage";

    public Locator(INavigationService navigationService)
    {
        //Setup services
        _kernel = new StandardKernel();
        _kernel.Bind<INavigationService>().ToConstant(navigationService);
        _kernel.Bind<IDialogService>().To<DialogService>();
    }

    public MainViewModel MainViewModel
    {
        get { return _kernel.Get<MainViewModel>(); }
    }

    public AlertViewModel AlertViewModel
    {
        get { return _kernel.Get<AlertViewModel>(); }
    }
}

Now instinctively something is telling me that it may be a smell to have my locator require a INavigationService, because my locator should not be concerned with this, right?

The reason I am doing this is because my NavigationService requires some configuration to map the views. I did attempt to bind the NavigationService as I did the dialog service, and then resolved it in my application start up and set the configurations, but it didn't seem to keep these configurations when it resolved my view model dependencies, e.g., the views could not be found in the dictionary. (No longer an issue, just a side note)

Here is the code in my application startup:

public App()
{
    InitializeComponent();

    //setup navigation service
    var navigation = new NavigationService();
    navigation.Configure(Locator.MainPage, typeof(MainPage));
    navigation.Configure(Locator.AlertPage, typeof(AlertPage));

    //Instantiate locator and add to resources for XAML reference
    Locator locator = new Locator(navigation);
    Current.Resources.Add("ServiceLocator", locator);

    //Create root navigation page
    var nav = new NavigationPage(new MainPage());

    //Assign main page and initialize navigation
    MainPage = nav;
    navigation.Initialize(nav);
}

Just in case you are wondering about the addition of the locator as an application resource, here is an example of how I am using that -- if you find it relevant:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             BindingContext="{Binding Path=AlertViewModel, Source={StaticResource ServiceLocator}}"
             x:Class="MvvmApp.Views.AlertPage">
    <ContentPage.Content>
        <StackLayout>
            <Entry x:Name="messageEntry" />
            <Button Text="Show Alert" 
                    Command="{Binding ShowAlertCommand}" 
                    CommandParameter="{Binding Source={x:Reference messageEntry}, Path=Text}"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

So ultimately my question is: Is what I am doing considered fundamentally wrong or a smell?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.