Powershell 跨多个函数共享参数定义的模式

Powershell 跨多个函数共享参数定义的模式,powershell,Powershell,我正在编写一个PowerShell模块,其中包含一组共享一组公共参数的不同函数。有了所有的参数元数据,这些函数变得很难管理。对一个参数进行一个小的更改,添加一个新参数,或者删除一个参数,这意味着我必须更新一堆不同的函数文件 除了模板化代码/代码生成之外,是否有人推荐在PowerShell中跨多个函数共享参数定义块的模式?我感觉到了您的痛苦。我已经遇到过很多次了。不幸的是,没有一个优秀的本机PowerShell解决方案可以解决所有问题。一些可能的选择: 写测试 简单地说:使用Pester,编写测试

我正在编写一个PowerShell模块,其中包含一组共享一组公共参数的不同函数。有了所有的参数元数据,这些函数变得很难管理。对一个参数进行一个小的更改,添加一个新参数,或者删除一个参数,这意味着我必须更新一堆不同的函数文件


除了模板化代码/代码生成之外,是否有人推荐在PowerShell中跨多个函数共享参数定义块的模式?

我感觉到了您的痛苦。我已经遇到过很多次了。不幸的是,没有一个优秀的本机PowerShell解决方案可以解决所有问题。一些可能的选择:

写测试 简单地说:使用Pester,编写测试。这并不能帮助您减少必须执行的复制/粘贴或重新键入相同参数块的数量,但它所做的是确保如果您确实在一个位置更改了参数,而忘记在其他位置更改它,或者进行了不兼容的更改,则测试将失败

当然,这意味着您必须以捕获这些问题的方式编写测试,但无论如何,您都应该这样做

我仍然没有像应该的那样频繁地编写测试,但是我认为这个选项提供了最好的总体结果,尽管它有很高的进入门槛

对参数使用强类型自定义类 在某种程度上,您可能会意识到需要到处传递一组参数,实际上,这些参数都在描述某个单元或概念(类)的不同方面(属性)

当您开始意识到参数之间相互依赖(比您在参数集上描述的要多)时,您会认识到这种情况,因此您可能会开始为其编写验证,并意识到它变得非常复杂

这里的解决方案是,这些参数应该是类的属性,以便类负责验证属性的值以及属性之间的关系

当您意识到参数中有不止一个这样的“组”,并且需要多个对象时,这将变得尤为明显和重要。如果参数集和验证超过1个,编写参数集和验证就会变得指数级地复杂,将它们划分为类将极大地缓解这一问题

缺点 在PowerShell中编写类有点糟糕。此外,没有导出PowerShell模块中定义的类的好方法,这意味着您的函数知道它,但模块的使用者不知道

这反过来意味着您不能将该类用作公共函数的参数

或者 用C#编写类。只要类是公共的,就不需要对程序集(.dll)执行任何特殊操作即可在PowerShell中使用它<代码>导入模块正常工作

但当然,这是一个完全不同的开发管道、构建过程、分发等

模板/代码生成
你碰过了,但是。。说真的,不要这样做。

如果函数共享那么多参数,我怀疑它们也有很多相同的代码。如果是这样的话,我会考虑下面的方法,我用在日志框架中,包括诸如“代码>日志条目< /代码>,<代码>日志调试< /COD>和<代码>日志VBOOSE :

  • 创建一个主函数(在我的例子中是
    日志条目
  • 为每个添加函数创建别名(在我的例子中是
    Log Debug
    详细记录日志
  • 通过使用检查函数名,从功能上转移
    $MyInvocation.InvocationName
比如:

函数日志条目{
Param(
...
)
...
If($MyInvocation.InvocationName-eq“Log Debug”){
...
}
If($MyInvocation.InvocationName-eq“Log Verbose”){
...
}
...
}
Set Alias Log Debug Log Entry-Description“默认情况下,日志调试条目不显示也不记录,但您可以通过更改common-Debug参数来显示它。”
Set Alias Log Verbose Log Entry-Description“默认情况下,不显示日志详细条目,但您可以通过更改common-Verbose参数来显示它。”

我在处理多个函数时做的一件事是开始使用哈希表在函数之间传递信息。我不需要几个参数,而是将所有内容存储在哈希表中,并且只需要这些参数,也许还需要一些其他参数。它使移动大量数据变得更加容易。@Jason+1-也发现这种方法很有用。在我的用例中,它是重写一个函数中的行为,因此可以省略1个或n个参数。如果你有一个具有许多可重用参数的大模块,我当然会选择在
C#
@MathiasR.Jessen中编写它,我也会这样做,但对许多人来说,这是一个很大的障碍。忘记了编写(主要是过程性的)脚本和OOP之间的语法差异和思维方式的改变,除了我提到的工作流(构建过程、版本控制、分发/打包)的巨大差异之外。它有许多优点,但要正确地管理它,有一个非常重要的额外工作负载,而只有脚本化的流程才能做到这一点。
Function Log-Entry {
<#
.Synopsis
    Log-Entry
.Description
    Displays and records cmdlet processing details in a file
#>
Param(
    ...
)
    ...
    If ($MyInvocation.InvocationName -eq "Log-Debug") {
        ...
    }
    If ($MyInvocation.InvocationName -eq "Log-Verbose") {
        ...
    }
    ...
}
Set-Alias Log-Debug    Log-Entry -Description "By default, the Log-Debug entry is not displayed and not recorded, but you can display it by changing the common -Debug parameter."
Set-Alias Log-Verbose  Log-Entry -Description "By default, the Log-Verbose entry is not displayed, but you can display it by changing the common -Verbose parameter."