架构 – 使用Xamarin Forms和ReactiveUI进行最先进的导航和路由

每年左右,我都有一个移动应用程序要做,我选择Xamarin Forms来做.在开始一个空白项目之前,我试图看看哪些框架和模式是“趋势”,我正在尝试构建一些可靠的东西.

在我的上一个应用程序中,我的研究使我开始使用Autofac for IoC和MvvmLight进行自定义设置,以及一系列与之相配的定制服务.

当我从网上来的时候,我没有逃到Reactive Extensions浪潮中,特别是作为Angular dev.
所以,这一次,我的设置基于Splat(我更喜欢Autofac,但是你知道的是tradeoffs)和ReactiveUI.

我很高兴.
但是,在我上次的应用程序中,还有一件事我真的很不高兴:导航.网上的大多数示例都是基本的(基本NavigationPages上的推/弹),没有那些做得很好的库,ReactiveUI的导航是……好吧,limited.

所以我必须制作我自己的根视图和导航服务,我的意思是,我没有写它,但是Kent Boogaart did in a blog post(如果你有兴趣回答我的问题,我建议你看一下impl来更好地了解它根据我的用例限制).它看起来不错.在我不得不处理更复杂的场景之前,我很喜欢它,比如导致MasterDetailPage的登录页面和TabbedPages.

再次,繁荣,我花了几个小时与模糊的X.F或Android例外和复杂的导航逻辑斗争,以便提供处理非常常见的用例的服务.我无法在网上找到有效的例子,看起来每个人都只使用三个屏幕构建示例应用程序而没有其他任何东西而不是NavigationPage.

我迷路了.

这是我目前拥有的API,来自Kent Boogaart的博客.

根视图:

public interface IView
{
    IObservable<IViewModel> PagePopped { get; }

    IObservable<Unit> PushPage(IViewModel pageViewModel, string contract, bool resetStack, bool animate);

    IObservable<Unit> PopPage(bool animate);

    IObservable<Unit> PushModal(IViewModel modalViewModel, string contract);

    IObservable<Unit> PopModal();
}

服务:

public interface IViewStackService
{
    IView View { get; }

    IObservable<IImmutableList<IViewModel>> PageStack { get; }

    IObservable<IImmutableList<IViewModel>> ModalStack { get; }

    IObservable<Unit> PushPage(
        IViewModel page,
        string contract = null,
        bool resetStack = false,
        bool animate = true);

    IObservable<Unit> PopPage(bool animate = true);

    IObservable<Unit> PushModal(IViewModel modal, string contract = null);

    IObservable<Unit> PopModal();
}

我正在尝试做什么:

--------------------------
| navigation page        | <- user not logged in, it's the root page
| --------- ------------ |
| | login | | register | |
| --------- ------------ |
|------------------------|
      |
      | -> user logs in
      |    via a hack, i can replace the root page with the masterdetails created by hand
      |    and reuse my previous root navigation page from the login screen as the new root,
      |    setting it as the Detail page (so the MasterDetail is not handled by my service)
      V
----------------------------------
| masterdetail page              |
| --------------------------     | -> this begins to get really complicated
| | detail 1 / tabbed page |     |
| | ---------- ----------  |     |
| | | page 1 | | page 2 |  |     |
| | ---------- ----------  |     |
| --------------------------     |
| ------------------------------ |
| | detail 2 / navigation page | | -> this could be doable with the current implementation
| | ----------  -------        | |    but erh..
| | | page 1 |->| etc |        | |
| | ----------  -------        | |
| ------------------------------ |
----------------------------------

如您所见,第一个问题是当前服务只处理一个根导航页面,我无法正确可靠地处理MasterDetailPages或TabbedPages.

所以我的整体问题是:你有很好的例子展示一个真正的导航应用程序吗?你有没有遇到同样的问题?你的方法是什么?我愿意接受评论,代码片段或NuGet包.一切都可以帮助我专注于实际的应用程序,而不是一遍又一遍地构建我自己的框架,而不是真的满意.

最佳答案 我使用MVVMV Framework Freshmvvm.它具有很好的导航功能,允许我在从登录堆栈移动到主堆栈时在导航“堆栈”之间进行交换.它具有与您显示的界面类似的界面.它允许我扩展或替换导航功能.它提供了一个可以换出的基本IOC容器.它可以扩展为支持标签页面的主要细节.我没有发现我不能使用它或扩展它的情况.

Here are the main details

And here is some more information about implementing custom navigation

点赞