可供类型转换器和标记扩展使用的服务上下文

支持类型转换器和标记扩展用法的类型的作者通常必须拥有用法在标记或周围对象图结构中的所在位置的相关上下文信息。 为了能正确实例化所提供的对象或者对对象图中的现有对象进行对象引用,可能需要此信息。 使用 .NET XAML 服务时,可能需要的上下文将作为一系列服务接口公开。 类型转换器或标记扩展支持代码可使用从 XamlObjectWriter 或相关类型传递且可用的服务提供程序上下文来查询服务。 可通过一个这样的服务来直接获取 XAML 架构上下文。 本主题介绍如何从值转换器实现访问服务上下文,并且列出了通常可用的服务及其角色。

获取服务

作为值转换器的实现者,你经常需要访问在其中应用了值转换器的某些类型的上下文。 此上下文可能包括诸如活动的 XAML 架构上下文、对 XAML 架构上下文和 XAML 对象编写器提供的类型映射系统的访问权限等信息。 可用于标记扩展或类型转换器实现的服务通过属于每种虚方法签名的一部分的上下文参数来传递。 在每种情况下,你都在上下文中实现了 IServiceProvider ,并且可以调用 IServiceProvider.GetService 来请求服务。

用于标记扩展的服务

MarkupExtension 只有一个虚方法 ProvideValue。 输入 serviceProvider 参数是 XAML 处理器调用标记扩展时服务与实现的通信方式。 下面的伪代码演示了标记扩展实现可如何在其 ProvideValue中查询服务:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    //...
    // Get the IXamlTypeResolver from the service provider
    if (serviceProvider == null)
    {
        throw new ArgumentNullException("serviceProvider");
    }
    IXamlTypeResolver xamlTypeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
    if (xamlTypeResolver == null)
    {
        throw new ArgumentException("IXamlTypeResolver");
    }
    //...
}

用于类型转换器的服务

TypeConverter 有四个虚方法,它们使用一个服务上下文并且都支持 XAML 用法。 每个方法都传递一个输入 context 参数。 此参数的类型为 ITypeDescriptorContext,但该接口继承 IServiceProvider,因此具有一个可用于类型转换器实现的 GetService 方法。

下面的伪代码演示了 XAML 用法的类型转换器实现可如何在它的一个替代(在本示例中为 ConvertFrom)中查询服务:

public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext,
  CultureInfo cultureInfo,
  object source)
{
    IRootObjectProvider rootProvider = typeDescriptorContext.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
    if (rootProvider != null && source is String)
    {
        //return something, else ...
    }
    throw GetConvertFromException(source);
}

用于值序列化程序的服务

对于值序列化程序上下文,使用特定于 ValueSerializerIValueSerializerContext的服务提供程序类型。 该上下文传递给四个 ValueSerializer 虚方法的替代。 从上下文调用 GetService 以获取服务。

使用 XAML 服务提供程序上下文

可供 GetService 访问可用于标记扩展或类型转换器的 XAML 服务的服务提供程序作为内部类实现,并且仅通过接口以及将其传递到相关上下文中的方式公开。 只要加载路径或保存路径的默认 .NET XAML 服务实现中的 XAML 处理操作调用需要服务上下文的相关标记扩展或类型转换器方法,就会传递此内部对象。 根据具体情况,系统服务上下文提供 MarkupExtensionContextTextSyntaxContext,但这两个特定类都是内部类。 你与这些类的交互仅限于通过 GetService从中请求服务。

.NET XAML 服务上下文中可用的服务

.NET XAML 服务为标记扩展、类型转换器、值序列化程序以及可能的其他用法定义服务。 以下各节介绍每种服务,并提供有关可如何在实现中使用服务的指导。

IServiceProvider

参考文档IServiceProvider

相关内容:.NET 中基于服务的基础结构的基本操作,以便你可以调用 IServiceProvider.GetService

ITypeDescriptorContext

参考文档ITypeDescriptorContext

派生自 IServiceProvider。 此类表示标准 TypeConverter 签名中的上下文; TypeConverter 是自 .NET Framework 1.0 起就已存在的类。 它早于用于字符串到值类型转换的 XAML 和 XAML TypeConverter 方案。 在 .NET XAML 服务上下文中,TypeConverter 的方法是显式实现的。 显式实现的行为向调用方指示 ITypeDescriptorContext API 与 XAML 类型系统无关,或者与 XAML 中的读取或写入对象无关。 ContainerInstancePropertyDescriptor 通常从 .NET XAML 服务上下文返回 null

IValueSerializerContext

参考文档IValueSerializerContext

派生自 ITypeDescriptorContext ,并且还依赖于显式实现以抑制有关 XAML 类型系统的错误含义。 支持 ValueSerializer上的静态查找帮助器方法。

IXamlTypeResolver

参考文档IXamlTypeResolver

由以下内容定义:System.Windows.Markup 命名空间、System.Xaml 程序集

相关内容: 加载路径方案以及与 XAML 架构上下文的交互

服务 API:Resolve

可能会影响 XAML 到 CLR 类型映射,当 XAML 编写器在对象图中构造 CLR 对象时,此映射是必需的。 Resolve 处理对应于 XAML 类型名称 (XamlType.Name) 的可能由前缀限定的字符串,并返回一个 CLR Type。 解析类型通常很大程度上取决于 XAML 架构上下文。 只有 XAML 架构上下文了解注意事项,如加载哪些程序集以及可以或应访问其中哪些程序集以进行类型解析。

IUriContext

参考文档IUriContext

由以下内容定义:System.Windows.Markup 命名空间、System.Xaml 程序集

相关内容: 是 URI 或 x:Uri 值的成员值的加载路径和保存路径处理。

服务 API:BaseUri

此服务报告一个全局可用的 URI 根(如果有)。 可使用此 URI 根将相对 URI 解析为绝对 URI,反之亦然。 此方案主要与由特定框架或框架中常用根元素类的功能公开的应用程序服务相关。 可以采用 XAML 读取器设置的形式建立基 URI,然后传递给 XAML 对象编写器并由此服务进行报告。

IAmbientProvider

参考文档IAmbientProvider

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关内容: 加载路径处理以及类型查找延迟或优化。

服务 API:GetAllAmbientValues、另外 3 个

XAML 中的环境概念是一种将类型的特定成员标记为环境的方法。 或者,某种类型也可以是环境,以便保留该类型实例的所有属性值都应视为环境属性。 沿 XAML 节点流前进或作为对象图中的后代的标记扩展或类型转换器可以在加载时访问环境属性或类型实例;也可以在保存时使用环境结构的知识。 这可能会影响其他服务(例如, IXamlTypeResolverx:Type)的类型解析所需的限定程度。 另请参阅 AmbientPropertyValue

IXamlSchemaContextProvider

参考文档IXamlSchemaContextProvider

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关内容: 加载路径以及必须将 XAML 类型解析为后备类型的任何操作。

服务 API:SchemaContext

对于任何推迟加载操作,XAML 架构上下文都是必需的,因为同一架构上下文必须作用于推迟的区域才能集成推迟的内容。 有关 XAML 架构上下文的角色的详细信息,请参阅 XAML Services

IRootObjectProvider

参考文档IRootObjectProvider

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关内容: 加载路径。

服务 API:RootObject

该服务与由特定框架或框架中常用根元素类的功能公开的应用程序服务相关。 一种获取根对象的情况是连接代码隐藏和事件连结。 例如, x:Class 的 WPF 实现用于 XAML 标记中任何其他位置处的任何事件处理程序特性的标记编译和连结。 标记与为标记编译定义分部类的代码隐藏的连接点在根元素处。

IXamlNamespaceResolver

参考文档IXamlNamespaceResolver

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关内容: 加载路径、保存路径。

服务 API:GetNamespace(用于加载路径)、GetNamespacePrefixes(用于保存路径)

IXamlNamespaceResolver 是一项服务,该服务可按照原始 XAML 标记中映射的方式基于 XAML 命名空间的前缀返回 XAML 命名空间标识符/URI。

IProvideValueTarget

参考文档IProvideValueTarget

由以下内容定义:System.Windows.Markup 命名空间、System.Xaml 程序集

相关内容: 加载路径和保存路径。

服务 API:TargetObjectTargetProperty

IProvideValueTarget 可使类型转换器或标记扩展能够获取有关加载时作用位置的上下文。 实现可能使用此上下文来使某个用法失效。 例如,WPF 在其某些标记扩展(例如 DynamicResourceExtension)中具有逻辑。 该逻辑检查 TargetProperty 以确保该扩展仅用于设置依赖项属性(或其他非依赖项属性的简短列表)。

IXamlNameResolver

参考文档IXamlNameResolver

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关: 加载路径对象关系图定义,解析由 x:Namex:Reference或特定于框架的技术标识的对象。

服务 API:Resolve;用于更高级场景(如处理前向引用)的其他 API

x:Reference 处理的 .NET XAML 服务实现依赖于此服务。 特定框架或支持框架的工具使用此服务进行 x:Name 处理或等效的(RuntimeNamePropertyAttribute 特性化)属性处理。

IDestinationTypeProvider

参考文档IDestinationTypeProvider

由以下内容定义:System.Xaml 命名空间、System.Xaml 程序集

相关内容: 间接 CLR 类型信息的加载路径解析。

服务 API:GetDestinationType

有关详细信息,请参阅 IDestinationTypeProvider

另请参阅