我可以使用界面在不同项目的ViewModel之间导航

时间:2014-03-20 15:49:51

标签: mvvmcross

我在不同的PCL项目上处理具有多个模块的应用程序。我无法在每个模块之间创建依赖关系。所以,我想知道是否可以使用接口在不同模块中从ViewModel导航。

考虑两个模块(PCL): MyApp.FooModule MyApp.BarModule 。每个模块都有ViewModel, FooModuleViewModel BarModuleViewModel 。接口存储在每个模块引用的另一个PCL项目中(例如 MyApp.Interfaces )。您可以在下面看到我的项目依赖项:

MyApp.Droid :MyApp.Interfaces,MyApp.FooModule,MyApp.BarModule

MyApp.FooModule :MyApp.Interfaces

MyApp.BarModule :MyApp.Interfaces

我尝试从 FooModuleViewModel 导航到 BarModuleViewModel ,所以在我的应用设置中我想写像这样的东西:

Mvx.RegisterType<IBarModuleViewModel, BarModuleViewModel>();

FooModuleViewModel

ShowViewModel<IBarModuleViewModel>();

实际上,当我实现这一点时,我有一个例外(由MvxAndroidViewsContainer抛出):

Exception masked KeyNotFoundException: Could not find view for IBarModuleViewModel

有没有办法做到这一点,还是我必须在 ShowViewModel 方法上使用“真实”类型?

1 个答案:

答案 0 :(得分:1)

这可以通过一些技巧实现。

首先,您可以使用具体的ViewModel类型,但提供某种IoC驱动的路由以允许ViewModel查找类型信息 - 例如

public interface IViewModelLookupService
{
    void Register(Type interfaceType, Type concreteType);
    Type Lookup(Type interfaceType);
}

然后可以使用以下代码填充单例实现:

lookupService.Register(typeof(IBarModuleViewModel), typeof(BarModuleViewModel));

然后可以使用以下方式显示视图模型:

var type = lookupService.Lookup(typeof(IBarModuleViewModel));
ShowViewModel(type);

除了&GT;对此的一种变体是使用enumstring名称而不是接口进行查找。


或者,第二种方法可能是在每个平台上覆盖您的演示者 - 这些都有一个界面:

public interface IMvxViewPresenter
{
    void Show(MvxViewModelRequest request);
    void ChangePresentation(MvxPresentationHint hint);
}

视图模型请求对象是:https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/ViewModels/MvxViewModelRequest.cs

如果您要覆盖void Show(MvxViewModelRequest request)方法,则可以使用此方法将任何MvxViewModelRequest替换为具体接口ViewModelType - 例如类似的东西:

 public override Show(MvxViewModelRequest request)
 {
     if (request.ViewModelType.IsInterface)
     {
          var concreteType = // TODO - lookup type here...
          request = new MvxViewModelRequest(concreteType, request.ParameterValues, request.PresentationValues, request.RequestedBy);
     }

     base.Show(request)
 }

这需要在每个平台上进行


其他方法也是可能的...... Mvx非常模块化,可以覆盖 - 维基页面可能有所帮助 - https://github.com/MvvmCross/MvvmCross/wiki