wpf - samples - ¿Está lista la producción de ReactiveUI?
xamarin forms ui samples (3)
He estado investigando la posibilidad de usar la interfaz de usuario reactiva en el código de producción. Algunas de las características son realmente atractivas, pero me preocupa tomar una dependencia de esta biblioteca. Éstas incluyen:
- Whacky nombres y convenciones. Por ejemplo, los miembros protegidos que comienzan con minúsculas y el método
RaiseAndSetIfChanged
dependen de su miembro privado que comience con un guión bajo. Entiendo que Paul Betts (autor de ReactiveUI) tiene antecedentes de Ruby, así que supongo que de ahí provienen los nombres extraños. Sin embargo, esto causará un problema real para mí, ya que la nomenclatura estándar (según Stylecop) se aplica a lo largo de mi proyecto. Incluso si no se hiciera cumplir, me preocuparía la incoherencia resultante al nombrar que esto causará. - La falta de documentación / muestras. Hay algo de documentación y una muestra solitaria. Sin embargo, la documentación es solo una serie de publicaciones de blog (antiguas) y la muestra se basa en la V2 de la biblioteca (ahora está en V4).
Diseño extraño, en partes. Por ejemplo, el registro se abstrae para no tomar una dependencia en un marco de registro específico. Lo suficientemente justo. Sin embargo, dado que uso log4net (y no NLog) necesitaré mi propio adaptador. Creo que eso requerirá que implemente
IRxUIFullLogger
, que tiene una gran cantidad de métodos (más de 50). Hubiera pensado que un enfoque mucho mejor sería definir una interfaz muy simple y luego proporcionar métodos de extensión dentro de ReactiveUI para facilitar todas las sobrecargas necesarias. Además, existe esta extraña interfaz IWantsToRegisterStuff de la que depende el ensamblaje NLog, de la que no podré depender (porque es una interfaz interna). Espero no necesitar eso ...De todos modos, mi preocupación aquí es el diseño general de la biblioteca. ¿Alguien ha sido mordido por esto?
- Ya estoy usando MVVM Light extensamente. Sé que Paul hizo una publicación en un blog donde explica que técnicamente puede usar ambas cosas, pero mi preocupación se centra más en la facilidad de mantenimiento. Sospecho que sería terriblemente confuso haber tenido ambos entremezclados en la base de código de uno.
¿Alguien tiene experiencia práctica con el uso de UI reactiva en producción? De ser así, ¿puede aliviar o abordar cualquiera de mis preocupaciones anteriores?
Estoy respondiendo como alguien que ha usado ReactiveUI en algunos sistemas de producción, ha tenido problemas con la forma en que RxUI hace las cosas, y ha enviado parches para tratar de solucionar los problemas que he tenido.
Descargo de responsabilidad: no uso todas las características de RxUI. La razón es que no estoy de acuerdo con la forma en que se han implementado esas características. Detallaré mis cambios a medida que avance.
Nombrando Pensé que esto también era extraño. Esta terminó siendo una de las características que realmente no uso. Uso PropertyChanged.Fody para tejer en la notificación de cambio usando AOP. Como resultado, mis propiedades se parecen a las propiedades automotrices.
Doco. Sí, podría haber más. Especialmente con las partes más nuevas como el enrutamiento. Posiblemente esta es una razón por la que no uso todo RxUI.
Explotación florestal. He tenido problemas con esto en el pasado. Ver solicitud de extracción 69 . Al final del día, veo a RxUI como un marco muy dogmático. Si no está de acuerdo con esa opinión, puede sugerir cambios, pero eso es todo. Opinionated no lo hace malo.
Yo uso RxUI con Caliburn Micro. CM maneja la ubicación y el enlace de View-ViewModel, Screen y Conductors. No utilizo el enlace convencional de CM. RxUI maneja los Comandos y el código INPC de ViewModel, y me permite reaccionar a los cambios de propiedad usando Reactive en lugar de los enfoques tradicionales. Al mantener estas cosas separadas, me resulta mucho más fácil mezclar las dos juntas.
¿Alguno de estos problemas tiene algo que ver con estar listo para la producción? Nop. ReactiveUI es estable, tiene una base de usuarios de tamaño decente, los problemas se resuelven rápidamente en el grupo de google y Paul es receptivo a la discusión.
Lo uso en producción y hasta ahora RxUI ha sido perfectamente estable. La aplicación ha tenido problemas de estabilidad, algunos relacionados con EMS, otros con un controlador UnhandledException que estaba causando más problemas de los que estaba resolviendo, pero no he tenido ningún problema con la parte de la aplicación ReactiveUI. Sin embargo, he tenido problemas con respecto a que ObservableForProperty no se haya activado en absoluto, lo que pude haber usado de manera incorrecta y funcioné de manera consistente (incorrectamente) en mi código de prueba y en la UI en tiempo de ejecución.
-1. Paul explica que _Upper se debe al uso de la reflexión para llegar al campo privado de su clase. Puede usar un bloque como el siguiente para tratar los mensajes de StyleCop y Resharper, que es fácil de generar (de la SmartTag de Resharper)
/// <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;
....
o cambie sus propiedades de lleno
/// <summary>Gets or sets a value indicating whether is selected.</summary>
public bool IsSelected
{
get { return _IsSelected; }
set { this.RaiseAndSetIfChanged(x => x.IsSelected, value); }
}
a sus partes componentes tales como
/// <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);
}
}
}
Este patrón también es útil cuando en realidad no se proporciona un descriptor de acceso de propiedad "simple", pero puede requerir una variante más derivada, donde establecer un valor afecta a otros muchos.
-2. Sí, la documentación no es ideal, pero descubrí que después de Rx, recoger las muestras de RxUI era bastante fácil. También observo que los saltos de 2-4 parecen haber venido con los cambios para admitir Windows 8 / Windows 8 Phone, y después de seleccionar ReactiveUI para una tienda de Windows, la compatibilidad con DotNet 4.5 es excelente. es decir, el uso de [CallerName] ahora significa que simplemente esto. RaiseAndSetIFChanged (value) no es necesario para la expresión.
-3. No tengo ningún comentario sobre el lado de la explotación de registros ya que no he elegido usarlo.
-4. No he mezclado ni combinado con otros frameworks tampoco.
También hay una lista de otros colaboradores de ReactiveUI 4.2 en http://blog.paulbetts.org/index.php/2012/12/16/reactiveui-4-2-is-released/ , incluido Phil Haack.
Repasemos sus inquietudes pieza por pieza:
# 1. "Whacky naming and conventions".
Ahora que ReactiveUI 4.1+ tiene CallerMemberName, no tiene que usar las convenciones (e incluso entonces, puede RxApp.GetFieldNameForPropertyFunc
través de RxApp.GetFieldNameForPropertyFunc
). Simplemente escriba una propiedad como:
int iCanNameThisWhateverIWant;
public int SomeProperty {
get { return iCanNameThisWhateverIWant; }
set { this.RaiseAndSetIfChanged(ref iCanNameThisWhateverIWant, value); }
}
# 2. Falta de documentación / muestras
Esto es legítimo, pero aquí hay algunos documentos / muestras más:
- http://docs.reactiveui.net/ (esta es la documentación oficial de ReactiveUI, un trabajo en progreso, pero definitivamente en el que desea comenzar)
- https://github.com/reactiveui/ReactiveUI.Samples
- https://github.com/reactiveui/RxUI_QCon
- https://github.com/play/play-windows
# 3. "Hubiera pensado que un enfoque mucho mejor sería definir una interfaz muy simple y luego proporcionar métodos de extensión dentro de ReactiveUI para facilitar todas las sobrecargas requeridas"
Implemente IRxUILogger
en IRxUILogger
lugar, tiene dos métodos escasos :) ReactiveUI completará el resto. IRxUIFullLogger
solo está allí si lo necesita.
"Además, existe esta extraña interfaz IWantsToRegisterStuff"
No necesita saber esto :) Esto es solo para tratar con ReactiveUI inicializándose para que no tenga que tener un código repetitivo.
- "Sospecho que sería terriblemente confuso tener ambos entremezclándose en la base de código de uno".
Realmente no. Solo piense en ello como "MVVM Light con SuperPowers".