Reputation: 297
I'm trying to inject INavigationService
into my ViewModel, so I can navigate between pages, but I don't know how to register ViewModel with parameter. Here's my App:
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
x:Class="PrismDemo.App" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<prism:PrismApplication.Resources>
<ResourceDictionary>
</ResourceDictionary>
</prism:PrismApplication.Resources>
</prism:PrismApplication>
and...
public partial class App
{
INavigationService _navigationService;
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
_navigationService = NavigationService;
NavigationService.NavigateAsync("MainNavigationPage/Start");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<MainNavigationPage>();
Container.RegisterTypeForNavigation<StartPage, StartPageViewModel>("Start");
Container.RegisterTypeForNavigation<MiddlePage, MiddlePageViewModel>("Middle");
Container.RegisterTypeForNavigation<LastPage, LastPageViewModel>("Last");
}
}
How can I inject _navigationService
into ViewModels?
Thanks for help
Upvotes: 0
Views: 825
Reputation: 3388
If you are using Prism
, than you should inherit your App
from PrismApplication
:
instead of public partial class App
should be public partial class App : PrismApplication
.
No need to declare INavigationService _navigationService;
in your App
class, because it's already declared in PrismApplication
as NavigationService
property.
Prism
uses IUnityContainer
as Dependency Injection framework, which means for you, that all, that you will register in container:
Container.RegisterType<ISomeService, SomeServiceImplementation>();
Unity container will automatically inject in constructor:
Define a constructor in the target class that takes as a parameter the concrete type of the dependent class. The Unity container will instantiate and inject an instance.
PrismApplication
registers INavigationService
in a container, so, as I understand, you don't need to register your own instance and you could just add parameter of type INavigationService
in constructor of view model and unity container will inject instance of registered type. The important thing, that you should give an exactly the navigationService name for your parameter, because Prism
"expects" such parameter name for navigation service.
Upvotes: 1
Reputation: 5799
You don't actually have to register the ViewModel directly as long as you have followed the convention {MyProjectName}.Views.{MyPage}
and {MyProjectName}.ViewModels.{MyPageViewModel}
To use INavigationService
in the ViewModel simply add it to the Constructor. Remember it is a named service so it must be named navigationService
. You can check out several examples in the Samples Repo.
public class MyPageViewModel
{
INavigationService _navigationService { get; }
public MyPageViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
NavigateCommand = new DelegateCommand<string>(OnNavigateCommandExecuted);
}
public DelegateCommand<string> NavigateCommand { get; }
public async void OnNavigateCommandExecuted(string path) =>
await _navigationService.NavigateAsync(path);
}
Upvotes: 1