使用Prism开发Xamarin Android应用启动时触发InvalidOperationException异常
嘿,我刚看完你的问题,这个错误其实是Prism依赖注入容器和Xamarin原生DependencyService的使用冲突导致的,咱们一步步来解决:
首先,错误提示当前类型MyApp.Abstractions.IFacebookManager是接口,无法构造的核心原因是:Prism的Unity容器根本不知道IFacebookManager的实现类是什么。你现在只通过DependencyService.Register<IFacebookManager, FacebookManager>()注册了映射,但Prism的ViewModel构造注入是从它自己的IoC容器里取实例的,这俩容器完全独立,所以找不到实现就报错了。
下面是具体的修改步骤:
1. 在Prism的平台初始化器中注册接口映射
打开MainActivity.cs里的AndroidInitializer类,把IFacebookManager的注册放到Prism的容器里,替换掉原来空的RegisterTypes方法:
public class AndroidInitializer : IPlatformInitializer { public void RegisterTypes(IContainerRegistry containerRegistry) { // 告诉Prism容器:IFacebookManager的实现是FacebookManager containerRegistry.Register<IFacebookManager, FacebookManager>(); } }
2. 移除DependencyService的注册代码
删掉MainActivity.cs中OnCreate方法里的这一行,我们不再用原生的DependencyService来管理这个依赖了:
DependencyService.Register<IFacebookManager, FacebookManager>();
3. 修改OnActivityResult中获取实例的方式
原来用DependencyService拿实例的代码,改成从Prism容器里获取:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); // 从Prism应用容器中解析IFacebookManager实例 var container = ((PrismApplication)Application.Current).Container; var manager = container.Resolve<IFacebookManager>(); if (manager != null) { (manager as FacebookManager)._callbackManager.OnActivityResult(requestCode, (int)resultCode, data); } }
4. 优化App.xaml.cs中的服务注册(可选但推荐)
你在OnInitialized里用了自己的ServiceResolver来注册ICloudService,其实Prism的容器完全可以接管这个工作,把注册移到RegisterTypes方法里,统一管理所有依赖:
protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<NavigationPage>(); containerRegistry.RegisterForNavigation<EntryPage, EntryPageViewModel>(); // 把ICloudService也交给Prism容器管理 containerRegistry.Register<ICloudService, AzureCloudService>(); }
然后删掉OnInitialized里的ServiceResolver.Instance.Add<ICloudService, AzureCloudService>();这一行,避免多容器管理带来的混乱。
为什么之前的代码不行?
Prism的ViewModel构造注入是依赖它自己的IoC容器(这里是Unity),和Xamarin的DependencyService是两个完全独立的服务定位器。当Prism尝试创建EntryPageViewModel时,找不到IFacebookManager的注册映射,就会直接抛出异常,导致ViewModel的构造函数断点根本没机会触发。
修改后,Prism容器能正确找到所有依赖的实现,就能正常创建ViewModel,你的断点也能正常触发了。
内容的提问来源于stack exchange,提问作者NSouth

