在 ColdFusion 中的另一个 cfc 的上下文中执行一个函数,同时遵守导入语句
Execute a function in the context of another cfc in ColdFusion while honoring import statements
背景
我正在尝试创建一个可以从 JSON 重构组件图的函数 componentFromJson
。我采用了一种简单的方法,我使用 getMetaData
来查找组件属性以实例化正确的类型。
函数的用法如下:comp = componentFromJson(json, 'RootComponentType')
问题
问题是属性的类型不一定是完全限定的,因为命名空间可能已被导入,如下所示。
<cfimport path="some.namespace.Test">
<cfcomponent>
<cfproperty name="test" type="Test">
</cfcomponent>
当我尝试从 componentFromJson
函数上下文执行 createObject('Test')
时,显然失败了,因为调用上下文没有导入。
我尝试了很多不同的方法来解决这个问题,包括临时在父组件上动态定义组件工厂函数,并使用 invoke
在父 CFC 的上下文中调用工厂函数,但是它没用。
例如
<cfscript>
parentCmp = createObject('SomeCmp');
parentCmp.createComponent = function (type) {
return createObject(type);
};
childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>
糟糕的解决方案
我现在能想到的解决这个问题的唯一方法是解析 CFC 的 ColdFusion 代码并提取导入语句,但我预计这对于这个目的来说太慢了。不仅如此,这还不能涵盖所有边缘情况。
想法?
我想知道是否有人对解决这个问题有更好的想法?我可以采取完全不同的方法吗?可能有一种方法可以使用 ColdFusion 运行时来执行此操作 类,但我还没有弄清楚。
好吧,事实证明,当您了解 ColdFusion 运行时的基础机制(我最初很难找到它)时,这并不难。
我终于发现表示为 coldfusion.runtime.TemplateProxy
的 ColdFusion 组件正在封装一个 coldfusion.runtime.CFPage
实例,该实例又具有 createObject
方法。
因此,这是我使用 Java 反射提出的解决方案:
<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>
背景
我正在尝试创建一个可以从 JSON 重构组件图的函数 componentFromJson
。我采用了一种简单的方法,我使用 getMetaData
来查找组件属性以实例化正确的类型。
函数的用法如下:comp = componentFromJson(json, 'RootComponentType')
问题
问题是属性的类型不一定是完全限定的,因为命名空间可能已被导入,如下所示。
<cfimport path="some.namespace.Test">
<cfcomponent>
<cfproperty name="test" type="Test">
</cfcomponent>
当我尝试从 componentFromJson
函数上下文执行 createObject('Test')
时,显然失败了,因为调用上下文没有导入。
我尝试了很多不同的方法来解决这个问题,包括临时在父组件上动态定义组件工厂函数,并使用 invoke
在父 CFC 的上下文中调用工厂函数,但是它没用。
例如
<cfscript>
parentCmp = createObject('SomeCmp');
parentCmp.createComponent = function (type) {
return createObject(type);
};
childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>
糟糕的解决方案
我现在能想到的解决这个问题的唯一方法是解析 CFC 的 ColdFusion 代码并提取导入语句,但我预计这对于这个目的来说太慢了。不仅如此,这还不能涵盖所有边缘情况。
想法?
我想知道是否有人对解决这个问题有更好的想法?我可以采取完全不同的方法吗?可能有一种方法可以使用 ColdFusion 运行时来执行此操作 类,但我还没有弄清楚。
好吧,事实证明,当您了解 ColdFusion 运行时的基础机制(我最初很难找到它)时,这并不难。
我终于发现表示为 coldfusion.runtime.TemplateProxy
的 ColdFusion 组件正在封装一个 coldfusion.runtime.CFPage
实例,该实例又具有 createObject
方法。
因此,这是我使用 Java 反射提出的解决方案:
<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>