I am trying to open a page using FreshMVVM. If the app is already running I want to plug into the exisiting navigation stack.
The page opens fine but when we try and navigate the user onward by pushing a new page onto the stack i get the following Exception
FreshTinyIoC.TinyIoCResolutionException: 'Resolve failed: IFreshNavigationService'
With a Call Stack of:
at FreshTinyIoC.FreshTinyIoCContainer.ResolveInternal (FreshTinyIoC.FreshTinyIoCContainer+TypeRegistration registration, FreshTinyIoC.NamedParameterOverloads parameters, FreshTinyIoC.ResolveOptions options) [0x00136] in <244cbb4b2b78473caee762c4138df3f3>:0
at FreshTinyIoC.FreshTinyIoCContainer.Resolve (System.Type resolveType, System.String name) [0x00013] in <244cbb4b2b78473caee762c4138df3f3>:0
at FreshTinyIoC.FreshTinyIoCContainer.Resolve[ResolveType] (System.String name) [0x00001] in <244cbb4b2b78473caee762c4138df3f3>:0
at FreshMvvm.FreshTinyIOCBuiltIn.Resolve[ResolveType] (System.String name) [0x00006] in <c1f1d60a460941bc82899cfb78f0c2ec>:0
at FreshMvvm.PageModelCoreMethods.PushPageModelWithPage (Xamarin.Forms.Page page, FreshMvvm.FreshBasePageModel pageModel, System.Object data, System.Boolean modal, System.Boolean animate) [0x001ca] in <c1f1d60a460941bc82899cfb78f0c2ec>:0
This comes from the following call to PushPageModel
return new FreshAwaitCommand(async (entryType, tcs) =>
{
await this.CoreMethods.PushPageModel(typeof(SignalHistoryViewModel), null, false, true);
tcs.SetResult(true);
});
The code I use to load the page when responding to the Notifcation tap is below. Note if there is not an existing Navigation I create a new container, if there is an existing one I want to Push onto that one. I am assuming that FreshMVVM is correctly initialised because otherwise I would not be able to load the first page after the tapping on Notification. The exception only throws when I try and load then next Page
Type viewModelType = Helpers.SignalStateToViewModelHelper.GetSignalDetailViewModelType((State)Enum.Parse(typeof(State), signalState));
var navigationStack = Application.Current.MainPage as NavigationPage;
if (navigationStack != null)
{
// Navigate within the existing navigation stack
var pageModel = FreshPageModelResolver.ResolvePageModel(viewModelType, true);
Device.BeginInvokeOnMainThread(async () =>
{
await navigationStack.PushAsync(FreshPageModelResolver.ResolvePageModel(viewModelType, null));
});
}
else
{
// Create a new navigation stack
var pageModel = FreshPageModelResolver.ResolvePageModel(viewModelType, true);
var navigationContainer = new FreshNavigationContainer(pageModel);
Device.BeginInvokeOnMainThread(() =>
{
Application.Current.MainPage = navigationContainer;
});
}
If I always create a new container the code never fails but that means it is a new Navigation and I cannot press back in the stack.
I solved this by explicitly registering a IFreshNavigationService.
FreshIOC.Container.Register<IFreshNavigationService>(freshNavigationContainer, Constants.DefaultNavigationServiceName);
This might sound like a "Doh!" or RTFM moment but it still surprises me because I am pushing the page into a running instance that obviously does have an IFreshNavigationService registered otherwise it would not have worked up to that point.
I can only assume that this is because I do properly understand the App lifecycle and when the page is created in code running from a Notification "delegate" it is running in a different context.