Skip to content

Commit 3f2df06

Browse files
authored
Add RxAppBuilder docs and update .NET SDK to 10 preview (#906)
* Add RxAppBuilder docs and update .NET SDK to 10 preview Introduced a new RxAppBuilder documentation page and linked it in the handbook index and table of contents. Updated the GitHub Actions workflow to use .NET 8, 9, and 10 preview with caching. Changed global.json to target .NET SDK 10.0.100-rc.2.25502.107 with prerelease enabled. Modernized array initialization in Build.cs. Clarified legacy and recommended approaches in the view-models boilerplate code documentation. * Update main.yml
1 parent e71741c commit 3f2df06

File tree

7 files changed

+147
-11
lines changed

7 files changed

+147
-11
lines changed

.github/workflows/main.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ jobs:
1010
build:
1111
runs-on: windows-latest
1212
steps:
13-
- name: 'Setup dotnet 6 / 7 / 8'
14-
uses: actions/setup-dotnet@v5
13+
- name: Setup .NET (With cache)
14+
uses: actions/setup-dotnet@v5.0.0
1515
with:
16-
dotnet-version: |
17-
6.0.x
18-
7.0.x
19-
8.0.x
16+
dotnet-version: |
17+
8.0.x
18+
9.0.x
19+
10.0.x
20+
dotnet-quality: 'preview'
2021

2122
- name: 'Setup Java JDK 11'
2223
uses: actions/[email protected]

build/Build.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Build : NukeBuild
2626
private static readonly string splat = nameof(splat);
2727
private static readonly string DynamicData = nameof(DynamicData);
2828
private static readonly string reactivemarbles = nameof(reactivemarbles);
29-
private static readonly string[] RxUIProjects = new string[] { reactiveui, akavache, fusillade, punchclock, splat, "ReactiveUI.Validation" };
29+
private static readonly string[] RxUIProjects = [reactiveui, akavache, fusillade, punchclock, splat, "ReactiveUI.Validation"];
3030

3131
private AbsolutePath RxUIAPIDirectory => RootDirectory / reactiveui / "api" / reactiveui;
3232
private AbsolutePath RxMAPIDirectory => RootDirectory / reactiveui / "api" / reactivemarbles;

global.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
2-
"msbuild-sdks": {
3-
"MSBuild.Sdk.Extras": "3.0.44"
4-
}
2+
"sdk": {
3+
"version": "10.0.100-rc.2.25502.107",
4+
"rollForward": "latestFeature",
5+
"allowPrerelease": true
6+
}
57
}

reactiveui/docs/handbook/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Order: 15
66
Welcome to the ReactiveUI Handbook. This section provides comprehensive documentation for using ReactiveUI with .NET 8 and the latest best practices. Explore the topics below to learn about core concepts, advanced features, platform-specific guidance, and related projects.
77

88
## Core Topics
9+
- [RxAppBuilder](rxappbuilder.md)
910
- [Commands](commands/index.md)
1011
- [Data Binding](data-binding/index.md)
1112
- [View Models](view-models/index.md)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# RxAppBuilder in ReactiveUI - introduced in V21.0.1
2+
3+
The `RxAppBuilder` class in ReactiveUI is responsible for initializing and configuring the ReactiveUI framework within your application.
4+
It provides a fluent API to set up various components and services that ReactiveUI relies on.
5+
It extends the capabilities of the Splat Builder and Splat AppLocator to register platform-specific services, views, view models, and other dependencies required for ReactiveUI to function correctly.
6+
7+
## Key Features of RxAppBuilder
8+
- **Fluent Configuration**: The `RxAppBuilder` class allows you to chain configuration methods to set up your application in a readable and maintainable way.
9+
- **Service Registration**: You can register services and dependencies that your application will use, such as view models, views, and other services.
10+
- **Platform Integration**: It provides methods to integrate ReactiveUI with different platforms, ensuring that the framework works seamlessly across various environments.
11+
- **Customization**: You can customize the behavior of ReactiveUI by configuring options and settings that suit your application's needs.
12+
- **Initialization**: The `RxAppBuilder` class includes methods to initialize the ReactiveUI framework, ensuring that all necessary components are set up before your application starts.
13+
14+
## Example Usage
15+
```csharp
16+
var rxuiInstance = RxAppBuilder.CreateReactiveUIBuilder()
17+
.WithWpf() // Register WPF platform services
18+
.WithViewsFromAssembly(typeof(App).Assembly) // Register views and view models
19+
.WithRegistration(locator =>
20+
{
21+
// Register IScreen as a singleton so all resolutions share the same Router
22+
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
23+
})
24+
.BuildApp();
25+
26+
var mainUIThreadScheduler = rxuiInstance.MainThreadScheduler;
27+
var taskpoolScheduler = rxuiInstance.TaskpoolScheduler;
28+
```
29+
30+
## Platform Support
31+
The `RxAppBuilder` class supports various platforms, including WPF, Xamarin.Forms, and others. You can use platform-specific methods to ensure that ReactiveUI is properly configured for the target environment.
32+
33+
ReactiveUI.AndroidX - `WithAndroidX()`
34+
ReactiveUI.WPF - `WithWpf()`
35+
ReactiveUI.Maui - `WithMaui()`
36+
ReactiveUI.Blazor - `WithBlazor()`
37+
ReactiveUI.WinForms - `WithWinForms()`
38+
ReactiveUI.WinUI - `WithWinUI()`
39+
40+
## Registering Views and ViewModels
41+
You can register views and view models from specific assemblies using the `WithViewsFromAssembly` method. This allows ReactiveUI to automatically discover and register your views and view models.
42+
```csharp
43+
.WithViewsFromAssembly(typeof(App).Assembly)
44+
```
45+
You can also register individual views and view models using the `WithView` and `WithViewModel` methods.
46+
```csharp
47+
.RegisterView<MainView, MainViewModel>()
48+
.RegisterSingletonView<SettingsView, SettingsViewModel>()
49+
.RegisterViewModel<SettingsViewModel>()
50+
.RegisterSingletonViewModel<SettingsViewModel>()
51+
```
52+
53+
## Custom Service Registration
54+
You can register custom services and dependencies using the `WithPlatformModule` method. This allows you to integrate your own platform-specific services into the ReactiveUI framework. Where T is a class that implements IWantsToRegisterStuff.
55+
```csharp
56+
.WithPlatformModule<Services.MyPlatformModule>()
57+
```
58+
## Configure Schedulers
59+
You can configure the main thread and task pool schedulers used by ReactiveUI using the `WithMainThreadScheduler` and `WithTaskpoolScheduler` methods.
60+
```csharp
61+
.WithMainThreadScheduler(DispatcherScheduler.Current)
62+
.WithTaskpoolScheduler(TaskPoolScheduler.Default)
63+
```
64+
65+
The default scheduler extensions register the RxApp.MainThreadScheduler and RxApp.TaskpoolScheduler to use the appropriate schedulers for the platform.
66+
This can be overridden by calling the above methods with `setRxApp = false` to prevent setting the RxApp static properties.
67+
68+
```csharp
69+
.WithMainThreadScheduler(DispatcherScheduler.Current, setRxApp: false)
70+
.WithTaskpoolScheduler(TaskPoolScheduler.Default, setRxApp: false)
71+
```
72+
73+
Each platform module also registers the appropriate default schedulers for that platform.
74+
Custom schedulers can be provided as needed.
75+
Each platform can be custom configured as needed.
76+
By default the platform registers the appropriate `Schedulers` for that platform, the relevant `PlatformServices`, and the relevant `PlatformModule`.
77+
78+
## Registration Options
79+
The `RxAppBuilder` class provides various options for registering views, view models, and services. You can choose to register them as singletons or transient instances based on your application's requirements.
80+
81+
One option is to use an immediate registration approach, where services are registered directly within the builder configuration.
82+
```csharp
83+
.WithRegistration(locator =>
84+
{
85+
// Register IScreen as a singleton so all resolutions share the same Router, this is applied immediately
86+
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
87+
})
88+
```
89+
Another option is to use a deferred registration approach, where services are registered as the builder is built.
90+
```csharp
91+
.WithRegistrationOnBuild(locator =>
92+
{
93+
// Register IScreen as a singleton so all resolutions share the same Router, this is applied after BuildApp is called
94+
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
95+
})
96+
```
97+
98+
## Using Splat Modules
99+
You can also use Splat modules to register services and dependencies. This allows you to leverage existing Splat modules or create your own for better organization.
100+
```csharp
101+
.WithSplatModule(new MyCustomSplatModule())
102+
.WithSplatModule<Services.MySplatModule>()
103+
```
104+
105+
## Building the App
106+
Once you have configured the `RxAppBuilder`, you can build the ReactiveUI application instance using the `BuildApp` method. This finalizes the configuration and prepares the application for use.
107+
```csharp
108+
var rxuiInstance = rxAppBuilder.BuildApp();
109+
var mainUIThreadScheduler = rxuiInstance.MainThreadScheduler;
110+
var taskpoolScheduler = rxuiInstance.TaskpoolScheduler;
111+
```
112+
113+
## WithInstance usage
114+
This allows you to get instances from the underlying Splat service locator.
115+
```csharp
116+
rxuiInstance.WithInstance<IScreen>(screen =>
117+
{ // Use the registered IScreen instance for other services that depend on it.
118+
screen.Router.Navigate.Execute(new MainViewModel(screen));
119+
})
120+
```
121+
122+
Up to 16 registered instances from Splat.AppLocator can be provided in a single WithInstance call.
123+
```csharp
124+
rxuiInstance.WithInstance<IScreen, IDataService, ILogger>((screen, dataService, logger) =>
125+
{
126+
// Use the registered instances for other services that depend on them.
127+
})
128+
```

reactiveui/docs/handbook/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
- name: Handbook
22
href: index.md
3+
- name: RxAppBuilder
4+
href: rxappbuilder.md
35
- name: Collections
46
href: collections.md
57
- name: Commands

reactiveui/docs/handbook/view-models/boilerplate-code.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# Source Generators and Fody, the easy way to create properties in ReactiveUI
22

3+
## Legacy Note
34
If you are tired of writing boilerplate code for property change notifications, you can try one of the following:
45
- [PropertyChanged.Fody](https://github.com/Fody/PropertyChanged) or
56
- [ReactiveUI.Fody](https://www.nuget.org/packages/ReactiveUI.Fody).
67

78
These two libraries are both based on [Fody](https://github.com/Fody) - an extensible tool for weaving .NET assemblies, and they'll
89
inject `INotifyPropertyChanged` code into decorated properties at compile time for you.
910

11+
## Recommend for new projects
1012
- [ReactiveUI.SourceGenerators](https://www.nuget.org/packages/ReactiveUI.SourceGenerators/)
1113

1214
This library is a Source Generator that generates properties and commands for you. It is a new way to generate properties and commands for ReactiveUI taking decorated fields and methods and generating the properties and ReactiveCommands for you.
@@ -499,7 +501,7 @@ using ReactiveUI.SourceGenerators.WinForms;
499501
public partial class MyCustomViewModelControlHost;
500502
```
501503

502-
# Using ReactiveUI.Fody
504+
# Using ReactiveUI.Fody - Legacy
503505

504506
With [ReactiveUI.Fody](https://www.nuget.org/packages/ReactiveUI.Fody/), you don't have to write boilerplate code for getters and setters of read-write properties — the package will do it automagically for you at compile time.
505507
All you have to do is annotate the property with the `[Reactive]` attribute, as shown below.

0 commit comments

Comments
 (0)