假设我有一个函数,其中注入了依赖项和一些参数,如下所示:
function Invoke-ACommandLaterOn
{
param
(
# ...
[string] $CommandName,
[object] $PipelineParams,
[object[]] $PositionalParams,
[hashtable]$NamedParams
# ...
)
Assert-ParameterBinding @PSBoundParameters
# ...
# Some complicated long-running call tree that eventually invokes
# something like
# $PipelineParams | & $CommandName @PositionalParams @NamedParams
# ...
}我想立即断言参数与$CommandName的绑定成功。这就是Assert-ParameterBinding要做的事情。然而,我不是很确定如何实现Assert-ParameterBinding。
当然,我可以尝试立即调用$CommandName,但在这种情况下,这样做会产生副作用,除非首先完成一堆其他长期运行的事情。
在不调用函数的情况下,如何断言绑定到函数的参数是否成功?
发布于 2017-09-16 04:45:35
如果您执行如下操作(在Assert-函数中):
$cmd = Get-Command $CommandName
$meta = [System.Management.Automation.CommandMetadata]::new($cmd)
$proxy = [System.Management.Automation.ProxyCommand]::Create($meta)
$code = $proxy -ireplace '(?sm)(?:begin|process|end)\s*\{.*','begin{}process{}end{}'
$sb = [scriptblock]::Create($code)
$PipeLineParams | & $sb @PositionalParams @NamedParams实际上,我不确定它是否适用于位置参数或飞溅两个不同的设置,从我的头顶(我没有做太多的测试)。
解释
我有一些想法。首先,参数绑定可能非常复杂。在管道调用的情况下,当命中不同的块时,绑定发生的方式也不同。
因此,让PowerShell处理这个问题可能是个好主意,方法是重新创建相同的函数,但主体什么也不做。
所以我使用了内置的方法来生成代理函数,因为它会处理所有这些杂乱的工作,然后粗暴地替换主体,这样它实际上就不会调用原始函数。
理想情况下,您将执行一个遵循所有常规参数绑定过程的调用,但最终什么也得不到。
将其包装在try/catch中或以其他方式测试错误应该是一个很好的测试,可以确定这是不是一个成功的调用。
这甚至可以处理动态参数。
可能有一些边缘情况下,这不是很有效,但我认为它们将是罕见的。
此外,ValidateScript属性和动态参数可能会产生副作用。
https://stackoverflow.com/questions/46243874
复制相似问题