I would like to know of there is a valid way to implement Prism in a existing Xamarin.Forms Shared project. I'm sure others would also like to know if they can profit from what Prism has to offer without having to convert their existing project to a PCL project. All existing examples I've found show a PCL project(probably for a good reason).
To try implementing Prism in my project I installed the Prims.Unity.Forms nuget to each platform project. I tried to inherit from PrismApplication:
public partial class App : PrismApplication
{ }
But, this does not work. The app class does not allow me to inherit from a different base class.
Adding the following lines to my android project did not help:
protected override void OnCreate(Bundle bundle)
{
LoadApplication(new App(new AndroidInitializer()));
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{ }
}
Perhaps I am missing something or trying something that structurally is not possible.
Yes, it's completely possible.
For example, for Prism and Unity you need:
<package id="Prism.Core" version="6.3.0" ... />
<package id="Prism.Forms" version="6.3.0" .../>
<package id="Prism.Unity.Forms" version="6.3.0" ... />
<package id="Unity" version="4.0.1" ... />
And move your existing page to the
Views
folder, but remember to adjust the namespaces or your binding just won't work.
Remember to change application base type in code and XAML.
using Prism.Unity;
using Xamarin.Forms;
namespace XamPrismShared
{
public partial class App : PrismApplication
{
public App (IPlatformInitializer platformInitializer):base(platformInitializer)
{
}
}
}
Implement OnInitialized and RegisterTypes. Remember that you need to register each type you want to use with Prism as a page.
using Prism.Unity;
using Xamarin.Forms;
namespace XamPrismShared
{
public partial class App : PrismApplication
{
public App (IPlatformInitializer platformInitializer):base(platformInitializer)
{
}
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MainPage");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<NavigationPage>();
Container.RegisterTypeForNavigation<MainPage>();
}
}
}
Add ViewModelLocator.AutowireViewModel="True"
to your existent views in order to allow Prism to automatically bind with their respective ViewModel.
<?xml version="1.0" encoding="utf-8" ?>
<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="x:Class="XamPrismShared.Views.MainPage"" Title="MainPage">
<Label Text="{Binding Title}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</ContentPage>
using Prism.Mvvm;
namespace XamPrismShared.ViewModels
{
public class MainPageViewModel : BindableBase
{
public MainPageViewModel()
{
Title = "Hi from Prism.";
}
public string Title { get; set; }
}
}
Add the missing platform initializers and fix Xamarin.Forms load.
For Android,
using Android.App;
using Android.Content.PM;
using Android.OS;
using Microsoft.Practices.Unity;
using Prism.Unity;
namespace XamPrismShared.Droid
{
[Activity (Label = "XamPrismShared", Icon = "@drawable/icon", Theme="@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate (Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new XamPrismShared.App(new AndroidPlatformInitializer()));
}
}
public class AndroidPlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{
}
}
}
For iOS,
using Foundation;
using Microsoft.Practices.Unity;
using Prism.Unity;
using UIKit;
namespace XamPrismShared.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
LoadApplication (new XamPrismShared.App(new iOSPlatformInitializer()));
return base.FinishedLaunching (app, options);
}
}
public class iOSPlatformInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{
}
}
}
If you have any question or want to check, you can review the code in Github https://github.com/jesulink2514/Xamarin-Prism-shared-project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With