41

我一直在研究在生产代码中使用 Reactive UI 的可行性。一些特性真的很吸引人,但我担心依赖这个库。这些包括:

  1. 古怪的命名和约定。例如,受保护的成员以小写开头,RaiseAndSetIfChanged方法取决于您的私有成员以下划线开头。我知道 Paul Betts(ReactiveUI 的作者)有 Ruby 的背景,所以我猜这就是奇怪命名的来源。然而,这会给我带来一个真正的问题,因为标准命名(根据 Stylecop)在我的项目中被强制执行。即使没有强制执行,我也会担心由此导致的命名不一致。

  2. 缺乏文档/样本。有一些文档和一个孤独的样本。但是,文档只是一系列(旧)博客文章,示例基于库的 V2(现在在 V4 上)。

  3. 奇怪的设计,部分。例如,日志是抽象的,以便不依赖特定的日志框架。很公平。但是,由于我使用 log4net(而不是 NLog),我需要自己的适配器。我认为这将需要我实现IRxUIFullLogger,其中包含大量的方法(超过 50 个)。我原以为更好的方法是定义一个非常简单的接口,然后在 ReactiveUI 中提供扩展方法以促进所有必要的重载。此外,还有IWantsToRegisterStuff一个 NLog 程序集所依赖的奇怪接口,我将无法依赖它(因为它是一个内部接口)。我希望我不需要那个...

    无论如何,我关心的是图书馆的整体设计。有没有人被这个咬过?

  4. 我已经在广泛使用 MVVM Light。我知道 Paul 写了一篇博文,他解释说你可以在技术上同时使用这两种方法,但我更关心的是可维护性。我怀疑将两者混合在一个人的代码库中会令人非常困惑。

有没有人有在生产中使用 Reactive UI 的实践经验?如果是这样,你能减轻或解决我上述的任何担忧吗?

4

3 回答 3

34

让我们逐个处理您的担忧:

#1。“古怪的命名和约定。”

现在 ReactiveUI 4.1+ 具有 CallerMemberName,您根本不必使用约定(即使这样,您也可以通过 覆盖它们RxApp.GetFieldNameForPropertyFunc)。只需将属性写为:

int iCanNameThisWhateverIWant;
public int SomeProperty {
    get { return iCanNameThisWhateverIWant; }
    set { this.RaiseAndSetIfChanged(ref iCanNameThisWhateverIWant, value); }
}

#2。缺乏文件/样本

这是合法的,但这里有更多文档/示例:

#3。“我原以为更好的方法是定义一个非常简单的接口,然后在 ReactiveUI 中提供扩展方法以促进所有必要的重载”

相反,实现IRxUILogger它,它只有很少的两个方法 :) ReactiveUI 将填补其余部分。IRxUIFullLogger只有在您需要时才会出现。

“另外,还有这个奇怪的 IWantsToRegisterStuff 接口”

你不需要知道这个:) 这只是为了处理 ReactiveUI 初始化本身,这样你就不必有样板代码。

  1. “我怀疑将两者混合在一个代码库中会令人非常困惑。”

并不真地。只需将其视为“具有 SuperPowers 的 MVVM 灯”。

于 2013-01-21T21:42:09.330 回答
13

我作为一个在一些生产系统中使用过 ReactiveUI,对 RxUI 做事的方式有问题,并提交了补丁来尝试修复我遇到的问题的人来回答。

免责声明:我没有使用 RxUI 的所有功能。原因是我不同意这些功能的实现方式。我会详细说明我的变化。

  1. 命名。我也觉得这很奇怪。这最终成为我并没有真正使用的功能之一。我使用 PropertyChanged.Fody 使用 AOP 编织更改通知。结果,我的属性看起来像自动属性。

  2. 多可。是的,可能还有更多。特别是对于路由等较新的部分。这可能是我不使用所有 RxUI 的原因。

  3. 记录。我过去遇到过这个问题。请参阅拉取请求 69。归根结底,我认为 RxUI 是一个非常固执己见的框架。如果您不同意该意见,您可以提出更改建议,仅此而已。固执己见并不会使事情变得糟糕。

  4. 我将 RxUI 与 Caliburn Micro 一起使用。CM 处理 View-ViewModel 位置和绑定、屏幕和导体。我不使用 CM 的约定绑定。RxUI 处理命令和 ViewModel INPC 代码,并允许我使用 Reactive 而不是传统方法对属性更改做出反应。通过将这些东西分开,我发现将两者混合在一起更容易。

Does any of these issues have anything to do with being production ready? Nope. ReactiveUI is stable, has a decently sized user base, problems get solved quickly in the google group and Paul is receptive to discussion.

于 2013-01-22T00:42:36.263 回答
5

我在生产中使用它,到目前为止,RxUI 一直非常稳定。该应用程序存在稳定性问题,其中一些与 EMS 有关,另一些与 UnhandledException 处理程序有关,该处理程序导致的问题比它解决的问题多,但我对应用程序的 ReactiveUI 部分没有任何问题。但是,我遇到了关于 ObservableForProperty 根本没有触发的问题,我可能使用不正确并且在我的测试代码以及​​运行时的 UI 中始终(错误地)工作。

-1。Paul 解释说 _Upper 是由于使用反射来获取班级中的私有字段。您可以使用如下块来处理 StyleCop 和 Resharper 消息,这很容易生成(来自 Resharper SmartTag)

    /// <summary>The xxx view model.</summary>
    public class XXXViewModel : ReactiveObject
    {
    #pragma warning disable 0649
    // ReSharper disable InconsistentNaming

    [SuppressMessage("StyleCop.CSharp.NamingRules", 
      "SA1306:FieldNamesMustBeginWithLowerCaseLetter",
      Justification = "Reviewed. ReactiveUI field.")]
    private readonly bool _IsRunning;

    [SuppressMessage("StyleCop.CSharp.NamingRules", 
      "SA1306:FieldNamesMustBeginWithLowerCaseLetter",
      Justification = "Reviewed. ReactiveUI field.")]
    private string _Name;
    ....

或从完整更改您的属性

    /// <summary>Gets or sets a value indicating whether is selected.</summary>
    public bool IsSelected
    {
        get { return _IsSelected; }
        set { this.RaiseAndSetIfChanged(x => x.IsSelected, value); }
    }

到它的组成部分,如

    /// <summary>Gets or sets a value indicating whether is selected.</summary>
    public bool IsSelected
    {
        get { return _isSelected; }
        set 
        { 
            if (_isSelected != value)
            {
                this.RaisePropertyChanging(x => x.IsSelected); 
                _isSelected = value;
                this.RaisPropertyChanged(x=>x.IsSelected);
            }
        }
    }

这种模式在您实际上不提供“简单”属性访问器的情况下也很有用,但可能需要更派生的变体,其中设置一个值会影响多个其他值。

-2。是的,文档并不理想,但我发现在 Rx 之后,获取 RxUI 样本非常容易。我还注意到,从 2->4 的跳跃似乎都伴随着支持 Windows 8/Windows 8 Phone 的更改,并且为 Windows Store App 选择了 ReactiveUI,那么 DotNet 4.5 支持非常好。即使用 [CallerName] 现在意味着您只需 this.RaiseAndSetIFChanged(value) 不需要表达式。

-3。由于我没有选择使用它,因此我没有关于日志记录方面的任何反馈。

-4。我也没有与其他框架混合和匹配。

在http://blog.paulbetts.org/index.php/2012/12/16/reactiveui-4-2-is-released/上还有一个 ReactiveUI 4.2 的其他贡献者列表,包括 Phil Haack。

于 2013-01-21T13:48:50.250 回答