Skip to content

Commit cab5e30

Browse files
committed
Split RxNet and RxUI md files
1 parent d48e5a0 commit cab5e30

File tree

3 files changed

+408
-274
lines changed

3 files changed

+408
-274
lines changed

README.md

+2-274
Original file line numberDiff line numberDiff line change
@@ -1,281 +1,9 @@
11
# Rx.Net-ReactiveUI-CheatSheet
22
A collection of links and snippets to resources, samples, answers, people, videos, etc. related to Rx.Net and ReactiveUI.
33

4-
## Table of Contents
4+
[Rx.Net CheatSheet](RxNet.md)
55

6-
#### [Sample Projects](#sample-projects-1)
7-
#### [Articles & Documentation](#articles-documentation--resources)
8-
#### [Videos](#videos-1)
9-
#### [Tips & Best Practices - ReactiveUI](#tips--best-practices---reactiveui-1)
10-
#### [People to Follow](#notable-people-to-follow)
11-
#### [ReactiveUI Glossary](#reactiveui-glossary-1)
12-
13-
## Sample Projects
14-
15-
_Some of these are pretty dated but still have a lot of relevance_
16-
17-
A lot of these are taken from [this thread](https://github.com/reactiveui/ReactiveUI/issues/687), but I find it easier to browse when it's organized by platform, like this.
18-
19-
### Xamarin.Forms
20-
21-
[WorkoutWotch - Xamarin Forms Video Series](https://github.com/kentcb/WorkoutWotch)
22-
23-
[Reactive Examples by TheEightBot](https://github.com/TheEightBot/Reactive-Examples)
24-
25-
[UnofficialGitterApp](https://github.com/flagbug/UnofficialGitterApp)
26-
27-
[XamarinEvolve2014 - Heavily commented demo app by Paul Betts](https://github.com/paulcbetts/XamarinEvolve2014)
28-
29-
### Android
30-
31-
[Burger ingredient streams demo with blog post](https://github.com/JonDouglas/BeingReactive)
32-
33-
[Espera.Mobile](https://github.com/flagbug/Espera.Mobile)
34-
35-
### iOS
36-
37-
[CodeHub - uses MVVMCross](https://github.com/CodeHubApp/CodeHub)
38-
39-
[ReactiveTableView & ReactiveCollectionView Demo](https://github.com/cabauman/ReactiveTableViewSource-Sample)
40-
41-
### WPF
42-
43-
[Sample code for the book "You, I, and ReactiveUI"](https://github.com/kentcb/YouIandReactiveUI)
44-
45-
[FirstsStepsRUI with blog post](https://github.com/kondaskondas/FirstsStepsRUI)
46-
47-
### UWP
48-
49-
[RxUI-UWP-Sample](https://github.com/moswald/RxUI-UWP-Sample)
50-
51-
## Articles, Documentation, & Resources
52-
53-
[IntroToRx](http://www.introtorx.com)
54-
55-
[RxViz](https://rxviz.com/) - interactive JavaScript with visualizations (I just wish a DotNet version of this existed)
56-
57-
[RxMarbles](http://rxmarbles.com/) - interactive visualizations
58-
59-
[ReactiveX.io](http://reactivex.io/) - Rx hub for all languages
60-
61-
[ReactiveUI Docs](https://reactiveui.net)
62-
63-
[101 Rx Samples](http://rxwiki.wikidot.com/101samples)
64-
65-
[Custom Routing in ReactiveUI](https://kent-boogaart.com/blog/custom-routing-in-reactiveui)
66-
67-
[Default schedulers for each observable operator](https://stackoverflow.com/a/15396488/5984310)
68-
69-
## Videos
70-
71-
[Reactive Extensions for .NET Developers with Michael Stonis (November 2018)](https://channel9.msdn.com/Shows/On-NET/Reactive-Extensions-for-NET-Developers?WT.mc_id=ondotnet-channel9-cephilli)
72-
73-
[Why You Should Be Building Better Mobile Apps with Reactive Programming – Michael Stonis](https://www.youtube.com/watch?v=DYEbUF4xs1Q)
74-
75-
[UniRx playlist, but also includes intro to Rx theory and operators](https://www.youtube.com/playlist?list=PLKERDLXpXl_gdZ7NAHkAxKf12g3oNjTAc)
76-
77-
## Tips & Best Practices - ReactiveUI
78-
79-
### Inject Service Locator interface via constructor
80-
81-
```
82-
public SuspensionHost(ISuspensionDriver driver = null)
83-
{
84-
driver = driver ?? Locator.Current.GetService<ISuspensionDriver>();
85-
}
86-
```
87-
88-
**Explanation:** This uses a Service Located interface for the default interface, but only if the caller didn't give an explicit one in the constructor. Far more straightforward to test in a unit test runner than trying to construct a sham IoC container, but still falls back to a default implementation at runtime.
89-
90-
**Source:** [https://stackoverflow.com/a/26924067/5984310](https://stackoverflow.com/a/26924067/5984310)
91-
92-
### Call async operations in the View constructor, rather than the ViewModel constructor.
93-
94-
```
95-
this.WhenAnyValue(x => x.ViewModel.LoadItems)
96-
.SelectMany(x => x.ExecuteAsync())
97-
.Subscribe();
98-
```
99-
100-
**Explanation:** Invoking async operations in the ViewModel constructor means that your ViewModel class becomes more difficult to test, because you always have to mock out the effects of calling LoadItems, even if the thing you are testing is unrelated.
101-
102-
**Source:** [https://codereview.stackexchange.com/a/74793](https://codereview.stackexchange.com/a/74793)
103-
104-
### When should I bother disposing of IDisposable objects?
105-
106-
1) No need
107-
108-
```
109-
public MyViewModel()
110-
{
111-
MyReactiveCommand
112-
.Execute()
113-
.Subscribe(...);
114-
}
115-
```
116-
117-
Quote by Kent Boogart (one of the ReactiveUI maintainers):
118-
119-
> When the execution of a ReactiveCommand completes, all observers are auto-unsubscribed anyway. Generally, subscriptions to pipelines that have a finite lifetime (eg. via a timeout) need not be disposed manually. Disposing of such a subscription is about as useful as disposing of a MemoryStream.
120-
121-
2) Do dispose
122-
123-
```
124-
public MyView()
125-
{
126-
this.WhenAnyValue(x => x.ViewModel)
127-
.Do(PopulateFromViewModel)
128-
.Subscribe();
129-
}
130-
```
131-
132-
This one is tricky. Disposing of this subscription is a must _if_ developing for a dependency property-based platform such as WPF or UWP. Quoting Paul Betts, this is because "[there's no non-leaky way to observe a dependency property](https://stackoverflow.com/a/22341350/5984310)," which is exactly what the ViewModel property of a ReactiveUserControl is. However, if you happen to know that your ViewModel won't change for the liftime of the view then you can make ViewModel a normal property, eliminating the need to dispose. For other platforms such as Xamarin.Forms, Xamarin.Android, and Xamarin.iOS there's no need to dispose because you're simply monitoring the property (ViewModel) on the view itself, so the subscription is attaching to PropertyChanged on that view. This means the view has a reference to itself and thus, doesn't prevent the it from being garbage collected.
133-
134-
3) Do dispose
135-
136-
```
137-
public MyViewModel()
138-
{
139-
SomeService.SomePipeline
140-
.Subscribe(...);
141-
}
142-
```
143-
144-
Services commonly have a longer lifetime than view models, especially in the case of singletons and global application variables. Therefore, it's vital that these kinds of subscriptions are disposed of.
145-
146-
4) No need
147-
148-
```
149-
public MyViewModel()
150-
{
151-
SomeService.SomePipelineModelingAsynchrony
152-
.Subscribe(...);
153-
}
154-
```
155-
156-
Pipelines modeling asynchrony can be relied upon to complete, and thus the subscription will be disposed of automatically via OnComplete (or OnError).
157-
158-
5) Do dispose
159-
160-
```
161-
public MyView()
162-
{
163-
this.WhenAnyValue(x => x.ViewModel.SomeProperty)
164-
.Do(AssignValueToViewControl)
165-
.Subscribe();
166-
}
167-
```
168-
169-
Now you're saying "attach to PropertyChanged on _this_ and tell me when the ViewModel property changes, then attach to PropertyChanged on _that_ (the view model) and tell me when SomeProperty changes." This implies the view model has a reference back to the view, which needs to be cleaned up or else the view model will keep the view alive.
170-
171-
6) Performance tip
172-
173-
```
174-
public MyView()
175-
{
176-
// For a dependency property-based platform such as WPF and UWP
177-
this.WhenActivated(
178-
disposables =>
179-
{
180-
this.WhenAnyValue(x => x.ViewModel)
181-
.Where(x => x != null)
182-
.Do(PopulateFromViewModel)
183-
.Subscribe()
184-
.DisposeWith(disposables);
185-
});
186-
187-
// For other platforms it can be simplified to the following
188-
this.WhenAnyValue(x => x.ViewModel)
189-
.Where(x => x != null)
190-
.Do(PopulateFromViewModel)
191-
.Subscribe()
192-
}
193-
194-
private void PopulateFromViewModel(MyViewModel vm)
195-
{
196-
// Assign values from vm to controls
197-
}
198-
```
199-
200-
More efficient than binding to properties. If your ViewModel properties don't change over time, definitely use this pattern. The _WhenActivated_ part is important for dependency property-based platforms (as mentioned in case 2) since it will handle disposing of the subscription every time the view is deactivated.
201-
202-
7) No need
203-
204-
```
205-
// Should I dispose of the IDisposable that WhenActivated returns?
206-
this.WhenActivated(
207-
disposables =>
208-
{
209-
...
210-
})
211-
```
212-
213-
Quote by Kent Boogart:
214-
215-
> If you're using WhenActivated in a view, when do you dispose of the disposable that it returns? You'd have to store it in a local field and make the view disposable. But then who disposes of the view? You'd need platform hooks to know when an appropriate time to dispose it is - not a trivial matter if that view is reused in virtualization scenarios. In addition to this, I have found that reactive code in VMs in particular tends to juggle a lot of disposables. Storing all those disposables away and attempting disposal tends to clutter the code and force the VM itself to be disposable, further confusing matters. Perf is another factor to consider, particularly on Android.
216-
217-
## Notable People to Follow
218-
219-
Paul Betts [@paulcbetts](https://twitter.com/paulcbetts)
220-
* [Github](https://github.com/paulcbetts)
221-
* [Book: Programming Reactive Extensions and LINQ](http://disq.us/url?url=http%3A%2F%2Fjliberty.me%2F2lYAZb8%3AI-DqcbqqiSnKie2L8J8U2hBCoS8&cuid=3716375)
222-
* [Stack Overflow - System.Reactive](https://stackoverflow.com/search?q=user:5728+[system.reactive])
223-
* [Stack Overflow - ReactiveUI](https://stackoverflow.com/search?q=user:5728+[reactiveui])
224-
225-
GeoffreyHuntley [@GeoffreyHuntley](https://twitter.com/GeoffreyHuntley)
226-
227-
Lee Campbell [@LeeRyanCampbell](https://twitter.com/leeryancampbell)
228-
* [Stack Overflow - System.Reactive](https://stackoverflow.com/search?q=user:393615+[system.reactive])
229-
230-
Kent Boogaart [@kent_boogaart](https://twitter.com/kent_boogaart)
231-
* [Blog](https://kent-boogaart.com/blog)
232-
* [Book: You, I, and ReactiveUI](https://kent-boogaart.com/you-i-and-reactiveui/)
233-
* [Github](https://github.com/kentcb)
234-
* [Stack Overflow - System.Reactive](https://stackoverflow.com/search?q=user:5380+[system.reactive])
235-
236-
James World [@jamesw0rld](https://twitter.com/jamesw0rld)
237-
* [Stack Overflow - System.Reactive](https://stackoverflow.com/search?q=user:87427+[system.reactive])
238-
* [Github](https://github.com/james-world)
239-
* [Blog](http://www.zerobugbuild.com/)
240-
241-
Dave Sexton [@IDaveSexton](https://twitter.com/idavesexton)
242-
* [Stack Overflow - System.Reactive](https://stackoverflow.com/search?q=user:3970148+[system.reactive])
243-
244-
[ReactiveUI Slack](https://reactivex.slack.com/messages/reactiveui/)
245-
246-
[ReactiveUI Twitter](https://twitter.com/reactivexui)
247-
248-
[Stack Overflow Top Users for System.Reactive](https://stackoverflow.com/tags/system.reactive/topusers)
249-
250-
[Stack Overflow Top Users for ReactiveUI](https://stackoverflow.com/tags/reactiveui/topusers)
251-
252-
## ReactiveUI Glossary
253-
254-
_WhenActivated_
255-
256-
**WhenActivated:** allows you to specify the things that should occur when a view or view model is activated and deactivated; requries that our view implements IActivatable; Typically, you don't need to worry about disposing of the disposable returned by WhenActivated. Views tend to deactivate naturally as a consequence of users navigating through your application and ReactiveUI's default IActivationForViewFetcher implementations.
257-
258-
**IActivatable:** think of it as IActivatableView; implemented by IViewFor; tag interface (no methods to implement)
259-
260-
**ISupportsActivation:** think of it as IActivatableViewModel; requires that the IViewFor invokes WhenActivated; can test view model activation and deactivation by calling Activate and Deactivate; implementing this interface more than once in a view model class hierarchy will result in view model activation failing to work correctly
261-
262-
**ViewModelActivator:** essentially a sink in which WhenActivated will register the blocks of activation logic provided by your view model
263-
264-
**IActivationForViewFetcher:** implements GetAffinityForView and GetActivationForView
265-
266-
**GetAffinityForView:** method of IActivationForViewFetcher; tells ReactiveUI how confident you are that your implementation of IActivationForViewFetcher can provide activation information for a given view; higher numbers returned by this method trump lower numbers returned by other implementations
267-
268-
**GetActivationForView:** method of IActivationForViewFetcher; returns IObservable<bool> that ticks true when the view is activated and false when the view is deactivated
269-
270-
_NAVIGATION_
271-
272-
**RoutingState:** NavigationStack, Navigate (ReactiveCommand), NavigateBack (ReactiveCommand), NavigateAndReset (ReactiveCommand)
273-
274-
**IScreen:** Router (RoutingState); root of a navigation stack; despite the name, its views don't _have to_ occupy the whole screen
275-
276-
**IRoutableViewModel:** UrlPathSegment (string), HostScreen (IScreen)
277-
278-
**RoutedViewHost:** platform-specific; monitors an instance of RoutingState, responding to any changes in the navigation stack by creating and embedding the appropriate view
6+
[ReactiveUI CheatSheet](RxUI.md)
2797

2808
## Contributing
2819

0 commit comments

Comments
 (0)