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

Kentico 13:注册自定义宏字段时获取当前文档的方法

Kentico 13 自定义宏字段获取当前文档的解决方案

一、直接从宏上下文获取当前文档(最简方案)

在宏场景下,无需依赖IPageDataContextRetriever,可以直接通过MacroContext.Current获取当前绑定的文档对象,完全避开DI的问题:

[assembly: RegisterExtension(typeof(MyMacroFields), typeof(TreeNode))]
public class MyMacroFields : MacroFieldContainer
{
    public const string TitleMacro = "MyMetaTitle";
    public const string DescriptionMacro = "MyMetaDescription";

    protected override void RegisterFields()
    {
        base.RegisterFields();

        // 从宏上下文获取当前文档
        var currentPage = MacroContext.Current?.CurrentObject as TreeNode;
        
        // 注册自定义宏字段
        RegisterField(TitleMacro, () => currentPage?.GetValue<string>("DocumentTitle") ?? "默认标题");
        RegisterField(DescriptionMacro, () => currentPage?.GetValue<string>("DocumentDescription") ?? "默认描述");
    }
}

二、通过服务定位器兼容DI(快速适配现有代码)

如果必须使用IPageDataContextRetriever,可以通过Kentico内置的Service.Resolve<T>()方法在需要时获取服务,不用构造函数注入,兼容原有的宏扩展注册方式:

[assembly: RegisterExtension(typeof(MyMacroFields), typeof(TreeNode))]
public class MyMacroFields : MacroFieldContainer
{
    public const string TitleMacro = "MyMetaTitle";
    public const string DescriptionMacro = "MyMetaDescription";

    protected override void RegisterFields()
    {
        base.RegisterFields();

        // 按需获取IPageDataContextRetriever实例
        var pageDataContextRetriever = Service.Resolve<IPageDataContextRetriever>();
        var currentPage = pageDataContextRetriever.TryRetrieve()?.Page;
        
        RegisterField(TitleMacro, () => currentPage?.GetValue<string>("DocumentTitle") ?? "默认标题");
        RegisterField(DescriptionMacro, () => currentPage?.GetValue<string>("DocumentDescription") ?? "默认描述");
    }
}

注意:服务定位器不符合DI最佳实践,仅作为特殊场景下的临时解决方案。

三、自定义宏扩展提供者实现完整DI(规范方案)

如果想严格遵循DI模式,可通过自定义宏扩展提供者来从服务容器中获取实例,步骤如下:

  1. 将宏字段容器注册为服务
public class CustomModule : Module
{
    public CustomModule() : base("CustomModule") { }

    protected override void OnInit()
    {
        base.OnInit();
        // 注册MyMacroFields为服务
        Service.Use<MyMacroFields>();
    }
}
  1. 创建自定义宏扩展提供者
public class CustomMacroExtensionProvider : MacroExtensionProvider
{
    private readonly IServiceProvider _serviceProvider;

    public CustomMacroExtensionProvider(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public override object GetInstance(Type extensionType, Type decoratedType, object decoratedObject)
    {
        if (extensionType == typeof(MyMacroFields))
        {
            // 从服务容器获取实例
            return _serviceProvider.GetService(extensionType);
        }
        return base.GetInstance(extensionType, decoratedType, decoratedObject);
    }
}
  1. 替换默认宏扩展提供者
protected override void OnInit()
{
    base.OnInit();
    Service.Use<MyMacroFields>();
    // 全局替换为自定义提供者
    MacroContext.GlobalProvider = new CustomMacroExtensionProvider(Service.ServiceProvider);
}
  1. 保留构造函数注入的宏字段容器
public class MyMacroFields : MacroFieldContainer, IService
{
    public const string TitleMacro = "MyMetaTitle";
    public const string DescriptionMacro = "MyMetaDescription";

    private readonly IPageDataContextRetriever _pageDataContextRetriever;

    public MyMacroFields(IPageDataContextRetriever pageDataContextRetriever)
    {
        _pageDataContextRetriever = pageDataContextRetriever;
    }

    protected override void RegisterFields()
    {
        base.RegisterFields();
        var currentPage = _pageDataContextRetriever.TryRetrieve()?.Page;
        
        RegisterField(TitleMacro, () => currentPage?.GetValue<string>("DocumentTitle") ?? "默认标题");
        RegisterField(DescriptionMacro, () => currentPage?.GetValue<string>("DocumentDescription") ?? "默认描述");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:04:56