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模式,可通过自定义宏扩展提供者来从服务容器中获取实例,步骤如下:
- 将宏字段容器注册为服务
public class CustomModule : Module { public CustomModule() : base("CustomModule") { } protected override void OnInit() { base.OnInit(); // 注册MyMacroFields为服务 Service.Use<MyMacroFields>(); } }
- 创建自定义宏扩展提供者
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); } }
- 替换默认宏扩展提供者
protected override void OnInit() { base.OnInit(); Service.Use<MyMacroFields>(); // 全局替换为自定义提供者 MacroContext.GlobalProvider = new CustomMacroExtensionProvider(Service.ServiceProvider); }
- 保留构造函数注入的宏字段容器
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
相关产品推荐
相关产品推荐

