Skip to main content

ferroui_reactiveui_controls/
ferro_binding_module.rs

1//! `FerroBindingModule` (ReactiveUI.Binding's integration, `...BindingModule.cs`).
2
3use crate::{FerroCreatesCommandBinding, FerroObjectObservableForProperty, FerroViewThreadInvoker};
4use ferroui_reactiveui::{ICreatesCommandBinding, ICreatesObservableForProperty, IViewThreadInvoker};
5use ferroui_splat::{IModule, IMutableDependencyResolver, MutableDependencyResolverExt};
6use std::rc::Rc;
7
8/// Registers the property observer of FerroUI objects, the command binder of FerroUI controls and
9/// the view thread invoker with the dependency resolver (`FerroBindingModule`).
10#[derive(Debug, Default, Clone, Copy)]
11pub struct FerroBindingModule;
12
13impl FerroBindingModule {
14    /// The module (`new FerroBindingModule()`).
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20impl IModule for FerroBindingModule {
21    /// Registers [`FerroObjectObservableForProperty`], [`FerroCreatesCommandBinding`] and the shared
22    /// [`FerroViewThreadInvoker`] as lazy singletons (`Configure`).
23    fn configure(&self, resolver: &dyn IMutableDependencyResolver) {
24        register_binding_integration(resolver);
25    }
26}
27
28/// Registers what [`FerroBindingModule`] registers with `resolver`: the property observer of
29/// FerroUI objects (a lazy singleton of `dyn ICreatesObservableForProperty`), the command binder of
30/// FerroUI controls (`dyn ICreatesCommandBinding`) and the shared view thread invoker
31/// (`dyn IViewThreadInvoker`).
32// Deviation (DEVIATIONS.md, ReactiveUI controls): the null check of the resolver has no
33// counterpart; the body of `Configure` is also a function, for the builder of the application.
34pub fn register_binding_integration(resolver: &dyn IMutableDependencyResolver) {
35    resolver.register_lazy_singleton::<dyn ICreatesObservableForProperty>(|| {
36        Some(Rc::new(FerroObjectObservableForProperty::new()) as Rc<dyn ICreatesObservableForProperty>)
37    });
38    resolver.register_lazy_singleton::<dyn ICreatesCommandBinding>(|| {
39        Some(Rc::new(FerroCreatesCommandBinding::new()) as Rc<dyn ICreatesCommandBinding>)
40    });
41    resolver.register_lazy_singleton::<dyn IViewThreadInvoker>(|| Some(FerroViewThreadInvoker::instance() as Rc<dyn IViewThreadInvoker>));
42}