You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中IRootObjectProvider与IProvideValueTarget服务注入问题求助

.NET MAUI 获取IRootObjectProvider与IProvideValueTarget的解决方法

核心原因

IRootObjectProvider和IProvideValueTarget是XAML解析器处理标记扩展(MarkupExtension)时临时注入的上下文服务,不会注册到全局DI容器(MauiContext.Services),对应的实现类XamlValueTargetProvider、XamlRootObjectProvider是内部类,无法直接引用。


可行解决方案

1. 利用标记扩展生命周期获取(推荐)

官方设计中,这两个服务仅在IMarkupExtension<T>.ProvideValue(IServiceProvider)方法的调用上下文内可用。如果你的验证逻辑和绑定相关,直接将验证逻辑封装为标记扩展:

public class ValidationExtension : IMarkupExtension<BindingBase>
{
    public BindingBase ProvideValue(IServiceProvider serviceProvider)
    {
        // 直接从方法参数的serviceProvider中获取服务
        var rootProvider = serviceProvider.GetRequiredService<IRootObjectProvider>();
        var targetProvider = serviceProvider.GetRequiredService<IProvideValueTarget>();

        var root = rootProvider.RootObject as BindableObject;
        var targetObject = targetProvider.TargetObject as BindableObject;

        // 执行你的验证逻辑
        // ...

        // 返回绑定对象(根据需求调整)
        return new Binding(nameof(YourViewModel.Property))
        {
            ValidatesOnNotifyDataErrors = true,
            // 其他绑定配置
        };
    }
}

在XAML中直接使用该扩展:

<Entry Text="{local:ValidationExtension}" />

2. 自定义接口实现(特殊场景用)

如果必须在Handler等非标记扩展场景中获取,需要自己实现这两个接口,手动注入上下文信息:

先实现自定义服务类:

// 自定义IRootObjectProvider实现
public class CustomRootObjectProvider : IRootObjectProvider
{
    public object RootObject { get; }

    public CustomRootObjectProvider(BindableObject root)
    {
        RootObject = root;
    }
}

// 自定义IProvideValueTarget实现
public class CustomValueTargetProvider : IProvideValueTarget
{
    public object TargetObject { get; }
    public object TargetProperty { get; }

    public CustomValueTargetProvider(BindableObject targetObject, BindableProperty targetProperty)
    {
        TargetObject = targetObject;
        TargetProperty = targetProperty;
    }
}

然后在需要的地方手动创建实例(或注册到局部DI容器):

// 假设已获取到当前根对象(如页面)和目标控件/属性
var currentPage = this as ContentPage;
var targetEntry = this.FindByName<Entry>("MyEntry");

// 创建自定义服务实例
var rootProvider = new CustomRootObjectProvider(currentPage);
var targetProvider = new CustomValueTargetProvider(targetEntry, Entry.TextProperty);

// 直接使用实例,或注册到局部ServiceProvider
var localServices = new ServiceCollection();
localServices.AddSingleton<IRootObjectProvider>(rootProvider);
localServices.AddSingleton<IProvideValueTarget>(targetProvider);
var localProvider = localServices.BuildServiceProvider();

// 后续通过localProvider获取服务

内容的提问来源于stack exchange,提问作者Wasyster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:52:52