NSouth
NSouth

Reputation: 5276

Prism with Xamarin for Android - InvalidOperationException on Launch

I'm new to Xamarin and Prism, so forgive me if I'm missing something obvious. I am following the example of this project in GitHub. However, I am getting the following error when running my Android project.

System.InvalidOperationException: The current type, MyApp.Abstractions.IFacebookManager, is an interface and cannot be constructed. Are you missing a type mapping?

The error is occurring in EntryPage.xaml.g.cs in the LoadFromXaml() method.

[global::Xamarin.Forms.Xaml.XamlFilePathAttribute("Views\\EntryPage.xaml")]
public partial class EntryPage : global::Xamarin.Forms.ContentPage {

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "2.0.0.0")]
    private void InitializeComponent() {
        // Exception thrown here!
        global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(EntryPage));
    }
}

This leads me to believe that I'm not using the IoC container properly, but I can't see what I'm doing differently from the example. The EntryPageViewModel's constructor takes IFacebookManager as a parameter and I understand that Unity should take care of this. I have a breakpoint on the constructor, but it's not being hit. This is a .NET Standard Xamarin solution. I would appreciate any help and guidance. Thank you!

Here's my App.xaml.cs

using MyApp.Abstractions;
using MyApp.Helpers;
using MyApp.Services;
using MyApp.ViewModels;
using MyApp.Views;
using Prism;
using Prism.Ioc;
using Prism.Unity;

using Xamarin.Forms;

namespace MyApp
{
    public partial class App : PrismApplication
    {
        public App(IPlatformInitializer initializer = null) : base(initializer) { }


        protected override void OnInitialized()
        {
            InitializeComponent();

            ServiceResolver.Instance.Add<ICloudService, AzureCloudService>();

            NavigationService.NavigateAsync("NavigationPage/EntryPage");            
        }



        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<EntryPage, EntryPageViewModel>();
        }
    }
}

Here's my MainActivity.cs

using Android.App;
using Android.Content.PM;
using Android.OS;
using MyApp.Droid.Services;
using MyApp.Abstractions;
using Android.Content;
using Xamarin.Facebook;
using Xamarin.Forms;
using Prism;
using Prism.Ioc;

namespace MyApp.Droid
{
    [Activity(Label = "MyApp", Icon = "@drawable/icon", Theme = "@style/MainTheme", Name = "com.mydomain.myapp.MainActivity", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        ICallbackManager fbCallbackManager;
        AndroidLoginProvider loginProvider;

        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;
            base.OnCreate(bundle);
            Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init();                        
            global::Xamarin.Forms.Forms.Init(this, bundle);
            DependencyService.Register<IFacebookManager, FacebookManager>();

            LoadApplication(new App(new AndroidInitializer()));
        }

        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            var manager = DependencyService.Get<IFacebookManager>();
            if (manager != null)
            {
                (manager as FacebookManager)._callbackManager.OnActivityResult(requestCode, (int)resultCode, data);
            }
        }
    }

    public class AndroidInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
        }
    }
}



public class AndroidInitializer : IPlatformInitializer
{
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
    }
}

Upvotes: 1

Views: 1834

Answers (2)

Jzrzmy
Jzrzmy

Reputation: 331

To complete the previous answer that helped me a lot to fix a similar issue: with prism 7, you need to resolve a dependency via IContainerProvider as follow:

var container = (App.Current as Prism.Unity.PrismApplication).Container;
var manager = container.Resolve<IFacebookManager>();

In this case, Unity is used as the IoC "container"

Upvotes: 2

Andres Castro
Andres Castro

Reputation: 1858

You are mixing the Xamarin Forms Dependency Service with the one provided with Prism.Unity

Instead of calling DependencyService.Register<IFacebookManager, FacebookManager>();

You need to register it with the AndroidInitializer .

public class AndroidInitializer : IPlatformInitializer
{
    public void RegisterTypes(IContainerRegistry container)
    {
        container.RegisterSingleton<IFacebookManager, FacebookManager>();
    }
}

You can then always resolve a dependency manually by calling App.Container.Resolve inside OnActivityResult.

Upvotes: 3

Related Questions