Powershell: better dynamicparam

Created on 16 Oct 2018  路  6Comments  路  Source: PowerShell/PowerShell

hello

its possible to reinvent the concept of dynamic param fo better and simple use

Steps to reproduce

dynamicparam {
  param(
    [parameter(mandatory)]
    $param1,
    [switch]
    $param2,
    [validateSet('a','b','c')]
    [char]$letter
  )

  # and here the logic

  return $dynamicObject
}
Issue-Discussion WG-Language

Most helpful comment

Honestly I'd much rather have a more seamless dynamic param approach. Basically, the current implementation is incredibly clunky.

I'd very much like if we could simply include dynamicparam as part of the param() block, perhaps as a full script block expression in place of a the typical [attributes()]$variable

param(
    [switch]
    $Param1,

    [DynamicParameter] {
        if ($Param1) { 
            [Parameter(Mandatory)]
            $Param2 = { Default-Value }
        }
        else { 
            [Parameter()]
            $Param3 = "Default Value"
        }
    },

    [switch]
    $Param3
)

To summarise — Idea, absolutely, needs some love. Implementation/Syntax? Could use some more thought.

All 6 comments

Honestly I'd much rather have a more seamless dynamic param approach. Basically, the current implementation is incredibly clunky.

I'd very much like if we could simply include dynamicparam as part of the param() block, perhaps as a full script block expression in place of a the typical [attributes()]$variable

param(
    [switch]
    $Param1,

    [DynamicParameter] {
        if ($Param1) { 
            [Parameter(Mandatory)]
            $Param2 = { Default-Value }
        }
        else { 
            [Parameter()]
            $Param3 = "Default Value"
        }
    },

    [switch]
    $Param3
)

To summarise — Idea, absolutely, needs some love. Implementation/Syntax? Could use some more thought.

How about this:

[cmdletbinding()]
param()

dynamicparam {
    class MyDynamicParams {
        [Parameter()][string]$ABC
    }

    return ($dynamicParams = [MyDynamicParams]::new())
}

begin {
    $dynamicParams.ABC
}

This works today.

Well, it's better than the "standard" implementations we usually see, but it's still very much an arcane syntax -- I don't think I've ever seen anyone talk about approaching it like that before.

Additionally, any parameter attributes that need script blocks cannot be used there, as classes prevent you from supplying script blocks to member attributes. So that rules out [ValidateScript()], [ArgumentCompleter()] and I think a few others. I can think of a few ways to skirt those rules in this specific case, but I think the case can still be made that dynamicparam... leaves a lot to be desired, unfortunately. 馃檨

I think @bielawb first proposed this technique, maybe in this talk.

Script blocks in attributes can be made to work with classes - it just requires delaying the creation of the scriptblock until the attribute is instantiated.

Dynamic parameters were never meant to be easy. There was always a strong desire for a declarative style, and whenever possible, improving on that instead of making dynamic parameters "easier".

As an example, parameter sets can get unwieldy in some cases. There were some discussions around "mutual exclusion sets" to make it easier to express things like "one of a,b,c and one of d,e,f". I don't recall any concrete proposals from those discussions, but it's an example of the strong desire to remain as declarative as possible.

Declarative is great, it doesn't have to be "easy". But I think dynamicparam strongly tends towards more "obscure" than "declarative", really. 馃槙

I also feel it is exceptionally difficult to document Dynamic Params. For instance they will never show up in Syntax Highlighting. There has to be a way to include this more explicitly in my opinion.

Was this page helpful?
0 / 5 - 0 ratings