ReactiveUI生产准备好了吗?

时间:2013-01-21 10:40:55

标签: wpf mvvm reactiveui

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

  1. Whacky命名和约定。例如,受保护的成员以小写字母开头,而RaiseAndSetIfChanged方法取决于以下划线开头的私有成员。我理解Paul Betts(ReactiveUI作者)有Ruby背景,所以我想这就是奇怪的命名源于此。但是,这会给我带来真正的问题,因为标准命名(根据Stylecop)在整个项目中都是强制执行的。即使没有强制执行,我也会担心这会导致命名的不一致。
  2. 缺乏文件/样本。有一些文档和一个孤独的样本。但是,文档只是一系列(旧的)博客文章,示例基于库的V2(现在是V4)。
  3. 奇怪的设计,部分。例如,日志记录是抽象的,以便不依赖于特定的日志记录框架。很公平。但是,由于我使用log4net(而不是NLog),我需要自己的适配器。我认为这将需要我实现IRxUIFullLogger,其中包含一个公制的方法(超过50)。我认为一个更好的方法是定义一个非常简单的接口,然后在ReactiveUI中提供扩展方法以促进所有必需的重载。另外,NLog程序集所依赖的这个奇怪的IWantsToRegisterStuff接口,我将无法依赖它(因为它是一个内部接口)。我希望我不需要那个......

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

  4. 我已经广泛使用MVVM Light了。我知道保罗写了一篇博文,他解释说你可以在技术上同时使用两者,但我更关心的是可维护性。我怀疑两者混合在一个代码库中会非常令人困惑。
  5. 有没有人有在生产中使用Reactive UI的实践经验?如果是这样,您是否能够减轻或解决我上述任何疑虑?

3 个答案:

答案 0 :(得分:32)

让我们一点一点地解决你的问题:

  

#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. “我怀疑两者混合在一个代码库中会非常令人困惑。”
  2.   

不是真的。只需将其视为“具有SuperPowers的MVVM Light”。

答案 1 :(得分:12)

我的回答是在一些生产系统中使用ReactiveUI的人,RxUI的工作方式存在问题,并提交了补丁以尝试解决我遇到过的问题。

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

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

  2. DOCO。是的,还有更多。尤其是路由等新部件。这可能是我不使用所有RxUI的原因。

  3. 记录日志。我以前遇到过这方面的问题。见pull request 69。在一天结束时,我将RxUI视为一个非常固执的框架。如果您不同意该意见,您可以建议更改,但这就是全部。意见不会让它变坏。

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

  5. 这些问题是否与生产准备有关?不。 ReactiveUI是稳定的,具有相当大的用户群,问题可以在google group中快速解决,Paul可以接受讨论。

答案 2 :(得分: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应用程序选择了ReactiveUI,然后DotNet 4.5支持非常出色。即使用[CallerName]现在意味着你只需要.RaiseAndSetIFChanged(value)就不需要表达式。

-3。由于我没有选择使用它,我对伐木方面没有任何反馈。

-4。我也没有和其他框架混在一起。

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