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

时间:2017-07-12 15:38:41

标签: powershell

我正在创作一个PowerShell模块,其中包含许多共享一组通用参数的不同函数。使用所有参数元数据,这些功能变得相当难以管理。对参数进行一处小改动,添加新参数或删除参数,意味着我必须更新一堆不同的函数文件。

除了模板化代码/代码生成之外,是否有人建议使用PowerShell中的许多函数共享参数定义块的模式?

2 个答案:

答案 0 :(得分:4)

我感觉到你的痛苦。我遇到过很多次。不幸的是,没有出色的原生PowerShell解决方案可以解决所有问题。一些可能的选择:

编写测试

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

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

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

为Params使用强类型自定义类

在某些时候,您可能会意识到需要在整个地方传递一组参数,实际上,这些参数都描述了某个单元或概念(类)的不同方面(属性)。

当你开始意识到参数相互依赖时(比你在参数集上描述的更多),你会认识到这种情况,所以你可能会开始为它编写验证并意识到它变得非常复杂。

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

当您意识到参数中有多个“组”并且需要多个对象时,这将变得尤为明显和重要。编写参数集和验证会变得更加复杂,其中任何超过1个,并将它们分解为类将以一种巨大的方式缓解这一点。

缺点

在PowerShell中编写类很糟糕。此外,没有好的方法可以导出PowerShell模块中定义的类,这意味着您的函数可以识别它,但模块的使用者不是。

反过来,这意味着您不能将该类用作公共函数的参数。 There are janky ways to export it, so you could do that, but...

替代地

用C#编写类。只要该类是公共的,您就不需要对程序集(.dll)执行任何特殊操作即可在PowerShell中使用它。 Import-Module只是有效。

但当然,这是一个完全不同的开发流程,构建流程,分发等。

模板/代码

你触及它,但是......严肃地说,不要这样做。

答案 1 :(得分:0)

如果函数共享那么多参数,我怀疑他们有很多共同的代码。如果是这种情况,我会考虑以下方法,我将其用于包含Log-EntryLog-DebugLog-Verbose等函数的日志记录框架:

  • 创建一个主要功能(在我的情况下为Log-Entry
  • 为每个添加功能创建别名(在我的情况下为Log-DebugLog-Verbose
  • 通过使用检查功能名称来功能转移 $MyInvocation.InvocationName

像:

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."