Updated for Prism.Forms 5.7.0-pre-1 (6/8/2015)

Just fives days ago, Microsoft announced that the ever popular and highly adopted Patterns & Practices Prism Library was being open sourced and is going to be run by a new team.    In that time, we have been hard at work getting a version of Prism out that supports the new Xamarin.Forms platform.  I am excited to announce, that we have released a very early preview of Prism for Xamarin.Forms that is available on NuGet now.

This preview has the following features included:

  • IoC with Unity (you will be able to provide your own container in a future release)
  • Event aggregation
  • Commanding
  • MVVM support
  • Navigation

Getting Started

Let’s see what it takes to create a Xamarin.Forms application with Prism.  Let’s start by creating a new blank Xamarin.Forms Portable application.

new Xamarin.Forms portable application

Next, lets go ahead and add our references to Prism for Xamarin.Forms using NuGet.  Right-click the Solution and click on “Manage NuGet Packages”.  Since this is a preview, you will have to change the package inclusion from “Stable Only” to “Include Prerelease”.  Now simply search for the package “Prism.Forms”.

image

Make sure you add the package to all the projects in the solution.

image

Next, we need to create a Bootstrapper class.  If you are a current Prism user, you are very familiar with this bootstrapper.  If not, the bootstrapper is simply a class that initializes all the services that Prism will be using.  This is what a simple bootstrapper class looks like.

public class Bootstrapper : UnityBootstrapper
{
     protected override Xamarin.Forms.Page CreateMainPage()
     {
         throw new NotImplementedException();
     }

     protected override void RegisterTypes()
     {
         throw new NotImplementedException();
     }
}

As you you can see we have two methods that we must implement.  CreateMainPage will return the page we want to use as the root page of the application.  RegisterTypes will be used to register our application types with our container of choice.  In the Preview, we are using Unity.

Now, let’s wire up our bootstrapper with our application.  Open up the App.cs and remove all the code in the class constructor.  Now we simply create an instance of our bootstrapper and call Run(this).

public class App : Application
{
     public App()
     {
         Bootstrapper bs = new Bootstrapper();
         bs.Run(this);
     }
}

Since we need a main page let’s go create one.  Let’s start by adding two folders to our application.  We want a folder for our Views, and a folder for our ViewModels.  I mean, we will be using MVVM after all.  Your project should look like this:

demo structure

In the Views folder create a MainPage, and return that page in your Bootstrapper.CreateMainPage method.  While you are in there, go ahead and remove the NotImplementedException line in the RegisterTypes.  We’ll see that in action later.

public class Bootstrapper : UnityBootstrapper
{
     protected override Xamarin.Forms.Page CreateMainPage()
     {
         return Container.Resolve<MainPage>();
     }

     protected override void RegisterTypes()
     {
        
     }
}

Now, let’s put some XAML in our MainPage view.  This is what I’ll be using for this demo.

<ContentPage xmlns=http://xamarin.com/schemas/2014/forms
              xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
              x:Class=PrismDemo.Views.MainPage>
   <StackLayout>
     <Label Text=“{Binding Title} VerticalOptions=Center HorizontalOptions=Center />
     <Button Command=“{Binding NavigateCommand} Text=Navigate />
   </StackLayout>
</ContentPage>

As you can see, we are expecting a ViewModel to bind to our MainPage view, so let’s go ahead and create one of those.  Right-click the ViewModels folder and add a new class.  Name it MainPageViewModel.  It is important that you name the ViewModel <PageName>ViewModel.  We will see why later.  This is what my ViewModel looks like:

public class MainPageViewModel : BindableBase
{
     string _title = “Main Page”;
     public string Title
     {
         get { return _title; }
         set { SetProperty(ref _title, value); }
     }

     public DelegateCommand NavigateCommand { get; set; }

     public MainPageViewModel()
     {
         NavigateCommand = new DelegateCommand(Navigate);
     }

     void Navigate()
     {

     }
}


BindableBase is a class provided by Prism that has your basic INotifyPropertyChanged implementation in it, and a helper method used for setting property values.  You may also recognize Prism’s DelegateCommand too.

Now, we have one more step.  We need to create the binding between the View and the ViewModel.  We will be using Prism’s ViewModelLocator to accomplish this.  So open up our MainPage.xaml and add a namespace to Prism’s ViewModelLocator.  Once you have added the namespace, set the AutoWireViewModel attached property to True.  That’s it!  This is what our View looks like now.

<ContentPage xmlns=http://xamarin.com/schemas/2014/forms
              xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
              xmlns:prism=clr-namespace:Prism.Mvvm;assembly=Prism.Forms
              prism:ViewModelLocator.AutowireViewModel=True
              x:Class=PrismDemo.Views.MainPage>
   <StackLayout>
     <Label Text=“{Binding Title} VerticalOptions=Center HorizontalOptions=Center />
     <Button Command=“{Binding NavigateCommand} Text=Navigate />
   </StackLayout>
</ContentPage>

Run the application, and let’s see what we have.

prism-xf-wp-1

As you can see, our MainPage is loaded, and the MainPageviewModel has been intantiated and set as the binding context of the page.  very cool.  So how did this work?  Well, the Prism ViewModelLocator is convention based.  To learn more about the ViewModelLocator, read the Getting Started with Prism’s ViewModelLocator post.

Now, let’s create a second View, and ViewModel that looks just like our MainPage, and start adding navigation to it.  This is what your solution should look like now.

image

Now in order to obtain the navigation service, we simply need to request it in the ViewModel constructor by adding a parameter of type INavigationService.  It’s important that we name the parameter “navigationService”.  This is case sensitive and will not work properly if not named correctly.  This will give use access to the proper INavigationService we need in order to navigate within our Xamarin.Forms application.  Now that we have the INavigationService, we can navigate to our ViewA created earlier.  Here is our MainPageViewModel now:

public class MainPageViewModel : BindableBase
{
    private readonly INavigationService _navigationService;

    string _title = "Main Page";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }

    public DelegateCommand NavigateCommand { get; set; }

    public MainPageViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;

        NavigateCommand = new DelegateCommand(Navigate);
    }

    void Navigate()
    {
        _navigationService.Navigate("ViewA");
    }
}

As you can see we are calling NavigationService.Navigate(“ViewA”), but how does that work?  Well, we need to actually register that view for navigation in our bootstrapper.  So let’s go back to the bootstrapper, and register the view with our container.

public class Bootstrapper : UnityBootstrapper
{
    protected override Page CreateMainPage()
    {
        return Container.Resolve<MainPage>();
    }

    protected override void RegisterTypes()
    {
        //default convention – NavigationService.Navigate("ViewA");
        Container.RegisterTypeForNavigation<ViewA>();

        //provide custom string as a unique name – NavigationService.Navigate("A");
        //Container.RegisterTypeForNavigation<ViewA>("A");

        //use a ViewModel class to act as the unique name – NavigationService.Navigate<ViewAViewModel>();
        //Container.RegisterTypeForNavigation<ViewA, ViewAViewModel>();
    }
}

By default, Prism will use the name of the object being registered as convention, but you can override that by providing your own key as a parameter.  There is also an overload that allows you to use a class type instead of a string.  Now when we run the application and click the button, we will navigate to our ViewA as expected.

prism-xf-wp-2

Now, let’s say we wanted to pass parameters to ViewA when we navigate to it.  Well, that’s easy.  We simply create a new NavigationParameters object and send them along with the navigation call.  This is what our MainPage.Navigate method looks like now.

void Navigate()
{
     NavigationParameters parameters = new NavigationParameters();
     parameters.Add(“message”, “Message from MainPage”);

      _navigationService.Navigate(“ViewA”, parameters);

Now, keep in mind that you can pass anything as a parameter.  You are not limited to just string, and you are not limited to one parameter.  You can pass any number of parameters.  The first parameter in the Add method is the unique key for the value.  This will be used to get the value from the parameters in the target view.  The second parameter is obviously the value.

So how do we get these parameters from the target view we are navigating to?  Well that’s easy.  We just need to implement the INavigationAware interface.

public class ViewAViewModel : BindableBase, INavigationAware
{
    private readonly INavigationService _navigationService;

    string _title = "View A";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }

    public DelegateCommand NavigateCommand { get; set; }

    public ViewAViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;
        
        NavigateCommand = new DelegateCommand(GoBack);
    }

    void GoBack()
    {
        _navigationService.GoBack();
    }

    public void OnNavigatedFrom(NavigationParameters parameters)
    {
        
    }

    public void OnNavigatedTo(NavigationParameters parameters)
    {
        Title = (string)parameters["message"];
    }        
}

This interface allows us to participate in the navigation process and gain access to the parameters being passed between ViewModels.  There is also the IConfirmNavigation interface which allows you to prevent a navigation from occurring based on the business logic from within the ViewModel.  Now when we run the application, we can pass a parameter to the target ViewA and display it in the view.

prism-xf-wp-3

The last think I was to show you in this post is the IEventAggregator.  The IEventAggregator gives you access to a publish/subscribe type eventing system throughout your application.  It is similar to the MessagingCenter built into Xamarin.Forms, but better.  To use it, you first nee to create a PubSubEvent.  Creating an event is easy.  Just create a class the derives form PubSubEvent<T>, where <T> is the object type of the payload, or message, that you will be sending with the event.

public class GoBackEvent : PubSubEvent<string>
{
}

Now you need a publisher to publish/send the event.  To publish the event, simply get the IEventAggregator in the constructor of your ViewModel and call the Publish method as follows.

public ViewAViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
{
    _navigationService = navigationService;
    _eventAggregator = eventAggregator;
    
    NavigateCommand = new DelegateCommand(GoBack);
}

void GoBack()
{
    _eventAggregator.GetEvent<GoBackEvent>().Publish("ViewA Message");
    _navigationService.GoBack();
}

Now, you need a subscriber.  In this case it will be our MainPageViewModel.  Modify the MainPageViewModel as follows:

public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
{
    _navigationService = navigationService;

    NavigateCommand = new DelegateCommand(Navigate);

    eventAggregator.GetEvent<GoBackEvent>().Subscribe(HandleEvent);
}

void HandleEvent(string payload)
{
    Title = payload;
}

As you can see, when the even is published by ViewAViewModel, the MainPageViewModel will respond to the event, take the payload and set it’s Title property to the value of the GoBackEvent payload.

prism-xf-wp-4

Summary

Thanks for hanging in there with me in this somewhat long post.  I hope this gives you enough information and guidance to get started using Prism for Xamarin.Forms.  I wanted to get this preview out to the community as quickly as possible in order to get your feedback on the direction Prism for Xamarin.Forms is going.  Let me know what you think about the API.  Tell me what sucks, but better yet, tell me what is great.  Be sure to check out this code on my GitHub, and start playing around.  If you have an idea that you would like to see implemented, be sure to fork our repository and submit a pull request.

As always, feel free contact me on my blog, connect with me on Twitter (@brianlagunas), or leave a comment below for any questions or comments you may have.

Brian Lagunas

View all posts

65 comments

  • Brian, Thanks for this, it’s absolutely awesome!

    I’d implemented something similar as you know, but I really like this. I’ll be having a play around with this and may end up replacing what I have with this. I’ll let you know how I get on.

    Jonathan

  • This is really great! Where should i singup to get the lastest news regarding the release status of this awesomeness?

    • Right now we don’t have a mechanism in place for subscribing to announcements. I am thinking of adding some type of newsletter signup on my blog so that I can reach people interested in the Prism announcements. For now, just subscribe to my RSS feed, and check back periodically until I can think of something.

  • This is great. So what other features of Prism would you like to include in this package that would make sense in Xamarin.Forms context? Any time frame for a release version?

    • Right now, I think the core concepts of Prism that make sense in Xamarin.Forms have already been ported over. The remaining concepts of Modularity and Regions don’t make sense in Xamarin.Forms. So now we are trying to discover the common issue and probalms Xamarin.Forms developers have when creating MVVM apps and solving those. So it is really about creating new guidance.

      The release time frame will really depend on community feedback. The more feedback we get, the closer to a release we will get. Otherwise, we will let the Preview remain until we are confident that we have implemented the correct guidance for the Xamarin.Forms platform.

  • Thanks Brian,

    After testing your example on Android I’ve noticed that when I navigate to pages it is done instantly. I am about to test this on iOS today. Should I use NavigationPage instead of ContentPage to get a navigation bar on iOS and Android and related slide animation?

    • Thanks for testing it out. I guess your first experience was a good one then :0). Yes, you can return a NavigationPage in the Bootstrapper CreateMainPage method. When using a NavigationPage, you will want to set the useModal parameter in the NavigationService.Navigate method to false. By default the NavigationService uses Push/Pop Modal, so you need to change it to use just Push.Pop Async with NavigationPages. We are still trying to determine if this is the best way to surface the difference in navigation patterns in Xamarin.Forms. We are also not sure if having the animated parameter on the NavigationService.Navigate method is necessary. Any feedback you can provide here would be great.

      • I would definitely leave animated parameter. Probably most of the time is a good thing to have a visual feedback that you are navigating from page to page but sometimes on rare occasions you wouldn’t want that. Having this option is better for the framework.

        • Do you think the animated parameter should be moved to the end of the Navigate method signature since it my be uncommon to turn the animation off?

          Another idea I had, since it may be uncommon, was to attribute the View to turn off the animation so it wouldn’t have to be in the method signature. What are your thoughts on that instead?

          • Yes, moving it to the end is a good idea. I would leave it in method signature though but maybe because I’m coming from iOS background and I’m used to presentViewController:animated: method. In my opinion transition from view to view (page to page) is something that doesn’t last long so a parameter on NavigationService.Navigate method makes sense because it is it’s responsibility how to navigate from point A to point B.

  • I am wondering also why do you think that modularity and regions doesn’t make sense for Xamarin Forms. I think it would be helpful when making an interface for Phone vs Tablet (so in that case regions more than modularity). Modularity makes sense when you would like to add some functionality at runtime, like plugins right? (and this is not allowed on mobile).

    • Modularity as it exists in Prism consists of loading assemblies at runtime, which is not supported by mobile. So, modularity in mobile would really just be splitting up your app into smaller projects, but having a strong reference to them. Prism doesn’t really help here. Regions allow you to compose your view with different smaller views, and it has it’s own region navigation service. This may overcomplicate a mobile app when you are trying to coordinate region navigation with page navigation. Now, Regions may make sense are larger devices like a tablet.

      Having said that, if the community thinks regions and region navigation would be beneficial, we can start looking at trying to port that over. Although, that would be no small task. Just keep in mind, that region navigation will not respect hardware buttons, and maybe they shouldn’t anyways.

      • Hi Brian, I think regions are definitely needed when looking at tablets, maybe even for phones when using MasterDetailPage or TabbedPage for navigation.
        On the modularity front, even if you will not be able to load assemblies dynamically, I think modules are important for structuring your code, keeping modules independant and reusing them across multiple platforms.
        I found in WPF and SL development with Prism over serveral years that using modules, combined with the RegionAdapters and RegionManager enabled a very clean code base. Also it enabled combining modules in various ways to create different flavours of applications, depending on the customer’s needs and the licensing model. Again, you may not be able to load assemblies dynamically, but you could selectively add them to the IOC, so only authorized modules will initialize.

        • We will be evaluating modularity and region navigation as it pertains to Xamarin.Forms. It may not make it into the V1, but it is something we have been discussing.

  • I use Prism daily with Silverlight, and have not been quite satisfied with other Xamarin MVVM frameworks.

    Will try this out asap and look forward to continued development!

  • Brian, congrats on getting this out. While I was at Microsoft, this is something I had hoped to do. It is good to see it come to fruition as I had a number of requests for this.

    • Thanks Blaine. Coming from you, that means a lot. You know, if you had time, I would appreciate it if you could give the code a “once over”. I’m not convinced with some of the approaches I took, and any validation or recommendations would be great.

  • Hi Brian. This is fantastic. I had been using XLabs take on Navigation but given that I am somewhat familiar with Prism I have jumped ship and hopped right on board here.

    One thing I am having some trouble with (and excuse my ignorance if the answer is obvious – I did say “somewhat” re: Prism experience above) is that I cannot find how to Pop from the ViewController that I just navigated to. I noticed the GoBack() procedure but when I tried to call that to “Pop” back to my previous page I received an Index out of range error. Now, it may be that I missed something in the configuration of the app which I will check but is there a different procedure I need to follow? Anything to do with NavigationJournal??

    Thanks again for the great preview guide.

    Tomás

    • My bad Brian.
      Turns out it was that it’s because I am using a NavigationPage as my root and without changing the default values in the GoBack() procedure it was attempting a PopModal. Changed it to a GoBack(true,false/*Not Modal*/) and all is fine.
      Thanks again for the guide and really looking forward to future developments of the library.

      • Just so you know, I have improved the GoBack logic to be smart enough to know whether to use PopAsync or PopModalAsync automatically. You can now pass parameters via GoBack which will also call OnNavigatedFrom/To on the respective pages. I haven’t published the NuGets, but the code has been checked into the repo.

  • Hi Brian,

    I have a Silverlight app that I am porting over. I see this package can not be added to portable class libraries (even though they target xamarin.ios, xamarin.droid). Is there a reason, this package can be added to only UI targetting projects?

    Thanks,
    Ankur

    • This package only supports Xamarin.Forms projects. We will be creating a NuGet package for the core Prism PCL which will have MVVM (commanding, BindableBase, VML, etc.), event aggregation, and logging support. What features are you trying to use in your PCL?

  • Hi Brian,

    Love your work on Prism and I think it is highly required for Xamarin.
    My question is regarding navigation. Currently in Xamarin when required to open a page of type NavigationPage the syntax requires creating a new NavigationPage and sending the original page as a param (e.g new NavigationPage(Container.Resolve())).
    The problem of course is how do I delegate this ability to the NavigationService?

    Thanks

    • Is this when the app first loads, or just anytime you need a NavigationPage? Do you have a sample to share that can demonstrate the scenario?

      • The issue is not relevant when opening the first screen, since this is the only time in which I initiate an instance of the main screen within the bootstrappers CreateMainPage override (e.g. return new NavigationPage(Container.Resolve());)

        The problem is when I am required to navigate from within a certain page. The way Xamarin works (from my understanding) is such that the initiator of the navigation needs to wrap the page inside a navigation page (I would think that this capability would be in the hands of the opened form and not the opening form). Therefore when trying to navigate using prism (e.g. NavigationService.Navigate(“my_view_name”);) I have no control of the page initiation and cannot wrap the page with a NavigationPage.

  • Hey Brian,

    The instructions are pretty simple, but I wonder how you’re adding the view. When I try to add a new item, there are no options for views – just xamarin types (contentpage, contentview, both of which are just .cs files), and other simple types like XML, JS, HTML, etc.

    I’m guessing that it thinks its smart enough to prevent me from trying to do that. I’m using VS 2013, and I have the latest Xamarin installed (as of yesterday), with a Xamarin.iOS business license and Xamarin.Android starter.

    If I work around that by adding an existing view from another project to modify, I get this error:

    Error 12 Build action ‘Page’ is not supported by the specific combination of the project’s targets. C:\dev\App\Client\Client\Views\LoginPage.xaml 0 0 Client

    It will actually deploy to the iPhoneSimulator, but I just get a blank screen. Can’t deploy to android because I don’t have the business license. Is that possibly because I have business on one and starter on the other?

    Does that mean anything to you? 🙂

    Thanks,

    Andy

    • Oh geez, newbie mistake. I totally did not see the “Forms XAML Page”

      🙂

  • Well, I’m doing something wrong, I suppose.

    When I start a new project, I can immediately deploy to the iPhoneSimulator and see the “Welcome to Xamarin Forms!” page.

    When I make these modifications (up to the very first instance where you suggest the app be run), and triple check my changes, I just get a blank page. I’ve started over 4 times already just to make sure I’m not missing anything simple, because no one else seems to have any trouble!

    Andy

    • Have you compared your project with the source code linked to this post? It really is extremely simple to setup the application, so I’m not sure what could be causing your issue. Feel free to send me your sample, and I’ll take a look at it.

      • Thanks, Brian! I was hoping the code was around, but didn’t see it initially. After you mentioned it, I found it.

        After looking at it, I noticed that your sample uses the “pre1” version of Prism.Forms. When I built my project from scratch, since I didn’t use the console, I was forced to use the “pre3” version.

        I downgraded my solution to “pre1”, and my it works fine now. Well, the title overlaps with the iPhone status bar at the top, but I’m sure that’s a simulator issue, nothing to do with Prism (would be interesting to hear if others see that as well).

        • Nothing much has changed from pre1 to pre3. That shouldn’t have made a difference. I have tested creating a pre3 app from scratch and it works every time. Could you share your project so that I can take a look at it?

          • Hey Brian, sorry for the delay – I’ve been getting buried in xamarin.forms. I appreciate the speedy responses. It turned out to be a combination of being a newbie / operator error / unexpected Visual Studio weirdness.

            I’m embarrassed to say that the resolution was jacked on my TV, so the simulator I was eyeballing from another room had a scrollbar that I missed when running 5/s and 6 because their resolutions are so much higher than the 4s.

            The second problem I discovered is that rebuild and clean do not work for me at all – there are lots of files left behind that do not get overwritten when running the app after making changes. So when I would make changes to XAML, they were not being incorporated in a new build.

            I finally tried deleting the contents of the Debug folders, and voila, changes started appearing!

            Everything is working great, and I really appreciate your work on this!

            Andy

  • Hello Brians,

    The Unity 4.0 was released. Please update Prism form Xamarin Form to compatible with Unity 4.0. Currently, Prism used Unity.3.5.1406 and I can’t upgrade to new Unity version due conflict assembly.

    error CS0012: The type ‘IUnityContainer’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘Microsoft.Practices.Unity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’.

    Thanks,
    Phuong

  • Brain,

    Thanks for all your work on this! I know you all are swamped, and I really hope someday my skillset is good enough to actually help out as you build out for Xamarin support, but I’m not there yet. And so, I apologize if this is the wrong place but I’m not having much luck finding the answer. Since this page always comes up as the top search when you look for PRISM and Xamarin, I hope you have time to answer here so others will be able to find it later.

    I’m using the 6.0.1 build of Prism.Forms; am I correct that currently Prism.Unity is more of a hybrid between Unity and Xamarin’s simple DependencyService?

    I see that Unity is used for navigation, but if I want to use PRISMs ability to autoinject via the constructor it seems Xamarin’s simple DependencyService is called. That of course doesn’t work if you need to inject something that has other dependencies in the constructor, since you must have a parameterless constructor for Xamarin’s service. Is the solution for now to just use Unity to manually do it in whatever constructor needs some other service? I’m pretty much stuck until I figure this out or go with a different MVVM solution…which I really, really don’t want to do since I’ve been very happy with Prism for Windows Store apps.

    Thank you again!

    • You are mistaken. Unity is a true DI contain, and does not rely on Xamarin’s DependencyService. Prism has a feature that will allow you to inject objects registered with Xamarin’s DependencyService, without having to call it directly, into your class constructor. If you ask for a registered dependency in your ViewModel constructor, you will get it, and any dependencies it requires, and so on. Prism uses real DI.

      • I’m glad to be mistaken, but confused by what I see happening.

        I’m following the UsingDependencyService example and I register each service using something like [assembly: Dependency(typeof(IMyService))].

        When I follow that method, when injecting a service into a ViewModel that is constructed typical to PRISM for winrt, such as:

        public ViewModel(IMyService myservice){_myservice = myservice}

        and MyService looking like:

        public MyService(IOtherservice myOtherservice, IEvenmoreService evenMoreservices) {_myOtherservice = myOrtherservice, …}

        I’m met with the error: Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed… MissingMethodException – Default constructor not found….at Xamarin.Forms.DependencyService.Get[IMyService]

        If I modify the constructor of the service (as a test) to public MyService(){manually link stuff here} PRISM is able to auto inject that service into the viewmodel.

        Reading the comment on the Prism Unity page saying “Prism will automatically resolve platform specific services from the Xamarin.Forms DependencyService when the interface is requested in a ViewModel constructor. No more calls to the static DependencyService.Get method anymore.” Got me thinking it’s using Xamarin to inject the service versus Unity. Add to that the mention in the debug output Xamarin.Forms.DependencyService.Get, and the fact that it won’t resolve unless I have a parameterless constructor which is a requirement of Xamarin, I hope you can understand my mistake. I apologize for that.

        I do get that Unity is a true DI container, everything works fine if I create a Unity container at startup, register each service with it (vs. Xamarin’s Dependency service) and then change all my services to a have a default constructor like:

        public MyService()
        {
        _myOtherService = App.Container.Resolve();

        }

        Doing it that way allows me to auto-inject the service into the viewmodel using PRISM. But now I’ve pushed the unit testing issue down to each service. Is there something that needs to be done so that Unity/PRISM can auto inject into a service vs a ViewModel? And after doing that would it be able to find the default constructor which has parameters, or is something else needed?

        Again thank you for you time, if there is a better place for me to post this let me know.

        • The UsingDependencyService sample is demonstrating how to use Prism to auto inject platform specific dependencies that are registered with Xamarin.Forms DependencyService. This is not a sample showing how to use Unity to register your own services.

          If you want Unity to know about your IMyService, then you have to register your services, and all dependencies, with the Unity container in the Bootstrapper in the RegisterTypes method.

          Container.RegisterType IMyService, MyService ();

          • Thank you so much! that is the missing piece of info I needed.

            It might be worth considering changing the description on the sample from “How to use Unity as a dependency service to handle your IoC.” To “How to use Prism to auto inject platform specific dependencies that are registered with Xamarin.Forms DependencyService”

            Again, your help and your work on this is much appreciated!

  • Another question I think people will run into, for which I can’t find an answer.

    The situation is: We have a Windows Store app we are porting. On launching the app we use code to figure out from roaming preferences to determine to which page we navigate them, and also, depending on the page, pass some parameters to personalize it. Prism makes that so easy…just load the settings, add some logic to determine which page to send them, and then use the navigation service to get them to the right place with the right personalization options. The simply put all the setup logic for each ViewModel into OnNavigatedTo and you’re done.

    From what I can see due to the way Xamarin works, Prism overrides the the MainPage call to return a specific page. I can see how I can move the logic from the Windows Store app to the BootStrapper MainPage override to determine to which page I navigate, but I don’t see a way to pass a parameter to it since we don’t use the navigation service for the main page.

    Also it seems from testing, the OnNavigatedTo event doesn’t trigger when MainPage() is run (which makes sense because we didn’t get there via the navigation service). This presents a dilemma for where one should put any setup/data loading actions for the main page. While I could use OnAppearing() to handle setup stuff for it, that leaves me without the option to simply pass a parameter when another page calls it via the navigation service, unless I do something even more messy by splitting things up between OnAppearing and OnNavigatedTo, which could make a huge mess of things and doesn’t solve the issue of how do I get a parameter to the page when the app is first run.

    For the main page, is there a “right way” to handle this?

    Again, I want to thank you for doing all the work to get Prism going with Xamarin.Forms, it’s seriously saved me a huge amount of time in porting things over, since most of the code already written for our windows app has required very little modification. Just a couple more viewmodel/navigation/service things to figure out, and then it’s just the “fun” of recreating all our views.

    • Copy and paste all of this on our issues page: https://github.com/PrismLibrary/Prism/issues

      I would love to hear more about this. I am actually in the process of overhauling the navigation service to support more advanced deep linking navigation scenarios. For example, when the app starts and is given a link from a website or other source, it navigates and retains the entire back stack.

      Imagine navigating like this:

      “android-app://HelloWorld/MyNavigationPage/ViewA?viewName=ViewA&id=1/ViewB?viewName=ViewB&id=2/ViewC?message=DeepLink&id=3/MyTabbedPage/ViewA/MyMasterDetail/ViewD”

      • WIll do.

        Having that ability would enable us to do some really cool targeted personalization stuff that we had on our “hope to do someday list”. Very cool!

  • I am trying to use a MasterDetailPage as app’s MainPage. Is there any tutorial/example about how to properly use Prism with such a scenario? Thought I should ask before I start experimenting on my own 🙂

    • I should add that I’d like to keep pages in XAML while most examples out there use C#. I managed to use XAML for the root MasterDetail page but I’m now wondering how to properly use it with Prism navigation system.

    • Actually, I am working on this right now! I am adding support for deep link navigation so you will be able to have something like “MyMasterDetail/ViewA/ViewB/MyNavigationPage/ViewC/MyTabbedPage”

      I have just about everything working on my local branch and should be checking it my v1 effort into the repo soon. I still have some small logic issues to work out and need to add support for CarouselPage, but I a making good progress.

      • I am really glad to read that you are currently working on the problem that Nicola has raised. Like Nicola, I spent a good deal of time on Friday trying to accomplish the same thing. I want to use a MasterDetailPage as my root page. The primary example that I was using as a guide is the following:

        https://www.syntaxismyui.com/xamarin-forms-masterdetail-page-navigation-recipe/

        It is a well-written tutorial that shows how the MasterDetailPage works (very simple). However, it is implemented in code rather than XAML, and does not use MVVM. I would like to determine the best approach to implementing this same behavior using XAML and Prism.

        Like Nicola, I was planning on spending more time trying to come up with my own solution. One of the primary questions that I ran into was whether or not to use a master/detail navigation mechanism like the one described in the tutorial, or whether to attempt to replace it with Prism navigation. If so, how should the view models for the detail pages be handled, etc? It is not obvious!

        I am really looking forward to seeing your approach.

        Thanks!!
        Craig

        • I have improved the logic for the navigation service to automatically work no matter what type of page you are using. If you are navigating from a MasterDetail it will set the Detail property, or if using a NavigationPage is will call PushAsync. Everything should just work. I have this in my latest local branch, and will be checking it into the repo soon. Just need ot add some more tests.

      • Excellent! looking forward to the update. @Craig: same boat, that tutorial is pretty good for a head start (minus Prism).

  • Brian,
    Thank you for a great project. I am a complete noob, but working through the examples and videos you have made on Prism 6, I have no doubt that it is the right solution for me.
    I do however have one question, that I can not find any info on – Will Prism.Forms work with a UWP project no that Forms 2 support UWP projects?
    Thanks a lot again for a great project.

    • The current 6.0.1 version is not built against Xamarin.Forms v2, but when we release the next update for Prism.Forms it will be. I am currently working on a very large navigation feature, so it may take a month or so before I release an official update. You can fork the repo, and upgrade yourself, and then reference your custom built assemblies until I can get the Nugets out.

  • Hi Brian,

    great work. I am currently using XLabs for the MVVM stuff but I am curious to use Prism instead. I watched your videos and the Navigation and Event stuff looks pretty useful.

    BUT: I have one question concerning Navigation (NavigationPage) I can not figure out.

    I have two pages and if I use this code line to navigate to the second page

    ==> this._navigationService.Navigate (“SecondPage”, param, true, true);

    it works using “useModalNavigation = true”. But I want to use a “normal” NavigationPage. But I can not figure out where to wrap my MainPage (StartPage) with the NavigationPage ?

    In the Bootstrapper I use the standard code:

    protected override void OnInitialized()
    {
    NavigationService.Navigate(“MainPage”);
    }

    protected override void RegisterTypes()
    {
    Container.RegisterTypeForNavigation();
    Container.RegisterTypeForNavigation ();
    }

    If I change the navigation code to

    this._navigationService.Navigate (“SecondPage”, param, false, true);

    I get the standard error that I have to wrap my page with a NavigationPage !
    If I change my MainPage in the XAML Code from ContentPage to NavigationPage I get the following error:

    System.InvalidOperationException: NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.

    So my question: Who do I use a NavigationPage correctly with Prism ?

    Thanx in advance

    Marco

    • Simple; just create an empty NavigationPage and register it with your container. Then navigate to the NavigationPage with the target page as the next page like this:

      protected override void RegisterTypes()
      {
      Container.RegisterTypeForNavigation-MyNavigationPage-();
      Container.RegisterTypeForNavigation-SecondPage- ();
      }

      _navigationService.Navigate(“MyNavigationPage/SecondPage”, params);

      Note: You don’t have to set the optional parameters (useModelNavigation, animated) because these are handled for you automatically. You only set these if you need to override the default behavior.

      The same syntax goes for MasterDetailPages, TabbedPages, and CarouselPages.

Follow Me

Follow me on Twitter, subscribe to my YouTube channel, and watch me stream live on Twitch.