Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ jobs:
build:
runs-on: windows-latest
steps:
- name: 'Setup dotnet 6 / 7 / 8'
uses: actions/setup-dotnet@v5
- name: Setup .NET (With cache)
uses: actions/setup-dotnet@v5.0.0
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
dotnet-version: |
8.0.x
9.0.x
10.0.x
dotnet-quality: 'preview'

- name: 'Setup Java JDK 11'
uses: actions/setup-java@v5.0.0
Expand Down
2 changes: 1 addition & 1 deletion build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Build : NukeBuild
private static readonly string splat = nameof(splat);
private static readonly string DynamicData = nameof(DynamicData);
private static readonly string reactivemarbles = nameof(reactivemarbles);
private static readonly string[] RxUIProjects = new string[] { reactiveui, akavache, fusillade, punchclock, splat, "ReactiveUI.Validation" };
private static readonly string[] RxUIProjects = [reactiveui, akavache, fusillade, punchclock, splat, "ReactiveUI.Validation"];

private AbsolutePath RxUIAPIDirectory => RootDirectory / reactiveui / "api" / reactiveui;
private AbsolutePath RxMAPIDirectory => RootDirectory / reactiveui / "api" / reactivemarbles;
Expand Down
8 changes: 5 additions & 3 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"msbuild-sdks": {
"MSBuild.Sdk.Extras": "3.0.44"
}
"sdk": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't need a global.json weird that you are

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's due to the fact that we are building all the repo's here, without it, the API's fail to be produced as the sln build fails. Once Net 10 becomes release and there is a VS2026 Action runner then this can be removed again.

"version": "10.0.100-rc.2.25502.107",
"rollForward": "latestFeature",
"allowPrerelease": true
}
}
1 change: 1 addition & 0 deletions reactiveui/docs/handbook/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Order: 15
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.

## Core Topics
- [RxAppBuilder](rxappbuilder.md)
- [Commands](commands/index.md)
- [Data Binding](data-binding/index.md)
- [View Models](view-models/index.md)
Expand Down
128 changes: 128 additions & 0 deletions reactiveui/docs/handbook/rxappbuilder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# RxAppBuilder in ReactiveUI - introduced in V21.0.1

The `RxAppBuilder` class in ReactiveUI is responsible for initializing and configuring the ReactiveUI framework within your application.
It provides a fluent API to set up various components and services that ReactiveUI relies on.
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.

## Key Features of RxAppBuilder
- **Fluent Configuration**: The `RxAppBuilder` class allows you to chain configuration methods to set up your application in a readable and maintainable way.
- **Service Registration**: You can register services and dependencies that your application will use, such as view models, views, and other services.
- **Platform Integration**: It provides methods to integrate ReactiveUI with different platforms, ensuring that the framework works seamlessly across various environments.
- **Customization**: You can customize the behavior of ReactiveUI by configuring options and settings that suit your application's needs.
- **Initialization**: The `RxAppBuilder` class includes methods to initialize the ReactiveUI framework, ensuring that all necessary components are set up before your application starts.

## Example Usage
```csharp
var rxuiInstance = RxAppBuilder.CreateReactiveUIBuilder()
.WithWpf() // Register WPF platform services
.WithViewsFromAssembly(typeof(App).Assembly) // Register views and view models
.WithRegistration(locator =>
{
// Register IScreen as a singleton so all resolutions share the same Router
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
})
.BuildApp();

var mainUIThreadScheduler = rxuiInstance.MainThreadScheduler;
var taskpoolScheduler = rxuiInstance.TaskpoolScheduler;
```

## Platform Support
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.

ReactiveUI.AndroidX - `WithAndroidX()`
ReactiveUI.WPF - `WithWpf()`
ReactiveUI.Maui - `WithMaui()`
ReactiveUI.Blazor - `WithBlazor()`
ReactiveUI.WinForms - `WithWinForms()`
ReactiveUI.WinUI - `WithWinUI()`

## Registering Views and ViewModels
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.
```csharp
.WithViewsFromAssembly(typeof(App).Assembly)
```
You can also register individual views and view models using the `WithView` and `WithViewModel` methods.
```csharp
.RegisterView<MainView, MainViewModel>()
.RegisterSingletonView<SettingsView, SettingsViewModel>()
.RegisterViewModel<SettingsViewModel>()
.RegisterSingletonViewModel<SettingsViewModel>()
```

## Custom Service Registration
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.
```csharp
.WithPlatformModule<Services.MyPlatformModule>()
```
## Configure Schedulers
You can configure the main thread and task pool schedulers used by ReactiveUI using the `WithMainThreadScheduler` and `WithTaskpoolScheduler` methods.
```csharp
.WithMainThreadScheduler(DispatcherScheduler.Current)
.WithTaskpoolScheduler(TaskPoolScheduler.Default)
```

The default scheduler extensions register the RxApp.MainThreadScheduler and RxApp.TaskpoolScheduler to use the appropriate schedulers for the platform.
This can be overridden by calling the above methods with `setRxApp = false` to prevent setting the RxApp static properties.

```csharp
.WithMainThreadScheduler(DispatcherScheduler.Current, setRxApp: false)
.WithTaskpoolScheduler(TaskPoolScheduler.Default, setRxApp: false)
```

Each platform module also registers the appropriate default schedulers for that platform.
Custom schedulers can be provided as needed.
Each platform can be custom configured as needed.
By default the platform registers the appropriate `Schedulers` for that platform, the relevant `PlatformServices`, and the relevant `PlatformModule`.

## Registration Options
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.

One option is to use an immediate registration approach, where services are registered directly within the builder configuration.
```csharp
.WithRegistration(locator =>
{
// Register IScreen as a singleton so all resolutions share the same Router, this is applied immediately
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
})
```
Another option is to use a deferred registration approach, where services are registered as the builder is built.
```csharp
.WithRegistrationOnBuild(locator =>
{
// Register IScreen as a singleton so all resolutions share the same Router, this is applied after BuildApp is called
locator.RegisterLazySingleton<IScreen>(static () => new AppBootstrapper());
})
```

## Using Splat Modules
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.
```csharp
.WithSplatModule(new MyCustomSplatModule())
.WithSplatModule<Services.MySplatModule>()
```

## Building the App
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.
```csharp
var rxuiInstance = rxAppBuilder.BuildApp();
var mainUIThreadScheduler = rxuiInstance.MainThreadScheduler;
var taskpoolScheduler = rxuiInstance.TaskpoolScheduler;
```

## WithInstance usage
This allows you to get instances from the underlying Splat service locator.
```csharp
rxuiInstance.WithInstance<IScreen>(screen =>
{ // Use the registered IScreen instance for other services that depend on it.
screen.Router.Navigate.Execute(new MainViewModel(screen));
})
```

Up to 16 registered instances from Splat.AppLocator can be provided in a single WithInstance call.
```csharp
rxuiInstance.WithInstance<IScreen, IDataService, ILogger>((screen, dataService, logger) =>
{
// Use the registered instances for other services that depend on them.
})
```
2 changes: 2 additions & 0 deletions reactiveui/docs/handbook/toc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
- name: Handbook
href: index.md
- name: RxAppBuilder
href: rxappbuilder.md
- name: Collections
href: collections.md
- name: Commands
Expand Down
4 changes: 3 additions & 1 deletion reactiveui/docs/handbook/view-models/boilerplate-code.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Source Generators and Fody, the easy way to create properties in ReactiveUI

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

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

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

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.
Expand Down Expand Up @@ -499,7 +501,7 @@ using ReactiveUI.SourceGenerators.WinForms;
public partial class MyCustomViewModelControlHost;
```

# Using ReactiveUI.Fody
# Using ReactiveUI.Fody - Legacy

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.
All you have to do is annotate the property with the `[Reactive]` attribute, as shown below.
Expand Down