ReactiveUI生产准备好了吗?

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

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

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

  4. 我已经广泛使用MVVM Light。 我知道保罗做了一个博客文章,他解释说,你可以在技术上同时使用这两个,但我更关心的是可维护性。 我怀疑这两个混合在一起的代码基础是非常混乱的。

有没有人有在生产中使用Reactive UI的实践经验? 如果是这样,你能消除或解决我的任何上述问题?

让我们一个接一个地检查您的疑虑:

#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. “我怀疑这两个人都混在一起的代码基础是非常混乱的。”

不是真的。 只要把它看成是“MVVM Light with SuperPowers”。

我回答的是在几个生产系统中使用过ReactiveUI的人,RxUI的工作方式有问题,并且已经提交了补丁来尝试解决我遇到的问题。

免责声明:我不使用RxUI的所有function。 原因是我不同意这些function的实施方式。 我将详细介绍我的变化。

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

  2. DOCO。 是的,可能会有更多。 特别是对于像布线这样的新部件。 这可能是我不使用所有RxUI的原因。

  3. 日志logging。 我过去遇到过这个问题。 请参阅拉请求69 。 在这一天结束的时候,我将RxUI视为一个非常有见地的框架。 如果你不同意这个观点,你可以提出改变build议,但这就是全部。 意见不会让它变糟糕。

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

这些问题是否与生产准备有关? 不。 ReactiveUI是稳定的,有一个体面的大小的用户群,问题得到迅速解决在谷歌组和保罗接受讨论。

我在生产中使用它,到目前为止,RxUI已经非常稳定。 该应用程序有稳定性方面的问题,一些与EMS有关,另外一些则带有一个UnhandledException处理程序,导致比解决问题更多的问题,但是我对应用程序的ReactiveUI部分没有任何问题。 然而,我有关于ObservableForProperty没有射击的问题,我可能不正确地使用,并在我的testing代码以及​​在运行时在UI中始终如一(不正确地)工作。

-1。 保罗解释说,上学是由于使用反思来进入你class上的私人领域。 您可以使用下面的块来处理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); } } } 

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

-2。 是的,文档不是理想的,但我发现,Rx之后,拿起RxUI样本很容易。 我也注意到,从2-> 4的跳跃似乎都有支持Windows 8 / Windows 8 Phone的变化,并且为Windows Store应用程序提供了ReactiveUI,那么DotNet 4.5支持就非常出色。 即使用[CallerName]现在意味着你只需要this.RaiseAndSetIFChanged(value)就不需要expression式。

-3。 我没有任何反馈,因为我没有select使用它。

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

ReactiveUI 4.2的其他贡献者名单也在http://blog.paulbetts.org/index.php/2012/12/16/reactiveui-4-2-is-released/ ,包括Phil Haack。