视图定位器
GodotViewLocator 是连接 ReactiveUI 视图解析与 Godot PackedScene 系统的桥梁。在 Avalonia 中,IViewLocator 通常通过 XAML DataTemplates 接入——平台在绑定时检查 ViewModel 的类型,并实例化 XAML 中声明的匹配 Control。Godot 没有等价的 DataTemplate 驱动的视图解析机制;场景通过 GD.Load<PackedScene>(path).Instantiate() 加载。GodotViewLocator 手动提供这一映射:将 ViewModel 类型注册到某个 .tscn 路径,ResolveView 便会加载并将该场景实例化为 IViewFor<TViewModel>。
将 GodotViewLocator 注册到 Splat 容器(正如 Autoload 通过 .WithGodotViewLocator(...) 所做的那样)是可选的。你也可以在需要时按需创建一个实例——例如 var locator = new GodotViewLocator(); locator.RegisterView<MyView, MyViewModel>(...);——并直接传给 RoutedViewController / ItemsBinder。Splat 注册只是为了方便,让那些通过 Locator.Current 解析的库组件能找到共享实例。
.WithGodotViewLocator(configure) 会将同一个实例同时注册为 IViewLocator 和 GodotViewLocator,因此通过 Locator.Current 解析到的定位器,正是你的 configure 回调所修改的那个实例。若跳过它,容器中保留的仍是默认的 IViewLocator(ReactiveUI 的 DefaultViewLocator),且不会注册任何 GodotViewLocator。
注册方法
在 GodotViewLocator 实例上注册 View 有三种方式:
var locator = new GodotViewLocator();
// 1. 显式注册视图 + ViewModel 类型
locator.RegisterView<MyView, MyViewModel>("res://Views/MyView.tscn");
// 若安装了 GodotSharp.SourceGenerators,也可:
locator.RegisterView<MyView, MyViewModel>(MyView.TscnFilePath);
// 2. 仅指定 ViewModel 类型(视图类型从 IViewFor<T> 实现推断)
locator.RegisterView<MyViewModel>("res://Views/MyView.tscn");
// 3. 通过反射扫描整个程序集——选取所有实现了
// IViewFor<TViewModel> 且暴露了静态 TscnFilePath 属性的具体类型
locator.RegisterViewsFromAssemblyViaReflection(typeof(MyView).Assembly);方式 3 依赖由 GodotSharp.SourceGenerators([SceneTree])生成的 TscnFilePath 静态属性。该包完全是可选的——方式 1 和 2 直接接受 "res://..." 路径字符串,无需源生成器。如果跳过它,只需为每个 ViewModel/View 对手动调用 RegisterView(...);只要注册到位,路由、ItemsBinder 及其他视图解析功能的工作方式完全相同。
解析原理
RegisterView<TViewModel>(path) 仅存储 ViewModel 类型和 .tscn 路径。在解析时,GodotViewLocator 执行 GD.Load<PackedScene>(path).Instantiate<IViewFor<TViewModel>>()——实际的 View 类由 .tscn 根脚本所实现的类型决定(它必须实现 IViewFor<TViewModel>)。RegisterView<TView, TViewModel>(...) 中的 <TView> 类型参数仅用于编译期校验,不影响解析结果。
ResolveView 通常由 ReactiveUI(或下文的示例 RoutedViewController)调用,而非你自己的代码;你只需保持注册信息是最新的即可。