Skip to content

ValidateSet should support a dynamically generated set #3744

Description

@lzybkr

People often use dynamic parameters so they can dynamically generate a ValidateSet attribute.

We should provide a simpler way to do this. One option is to accept a scriptblock:

param(
    [ValidateSet( { Get-ChildItem -ah | ForEach-Object Name } )]
    $HiddenFileName
)

Activity

  1. added
    WG-Enginecore PowerShell engine, interpreter, and runtime
    Issue-Enhancementthe issue is more of a feature request than a bug
    Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributors
    on May 9, 2017
  2. lfshr commented on May 9, 2017

    @lfshr

    This is a much better solution. Well played Jason Shirk (@lzybkr) like it!

  3. lzybkr commented on May 9, 2017

    @lzybkr
    ContributorAuthor

    We should also consider binary cmdlets. One option is to accept a type that implements an interface, something like:

    public interface IValidateSetGenerator
    {
        IEnumerable<string> Get();
    }
    public class MyValidateSetGenerator : IValidateSetGenerator
    {
        public IEnumerable<string> Get()
        {
            yield return "Something";
        }
    }
    ...
        [Parameter()]
        [ValidateSet(typeof(MyValidateSetGenerator)]
        public string Something { get; set; }

    This could probably work in PowerShell too (the interface would be defined in System.Management.Automation.dll.

    I think we'd need a way of passing $PSBoundParameters to truly cover most of the scenarios where people are resorting to dynamic parameters today.

  4. iSazonov commented on May 9, 2017

    @iSazonov
    Collaborator

    Recently I played with this and it seems like it might be too expensive due to IntelliSense.

  5. powercode commented on May 9, 2017

    @powercode
    Collaborator

    Ilya (@iSazonov) What is to expensive?

  6. iSazonov commented on May 10, 2017

    @iSazonov
    Collaborator

    Staffan Gustafsson (@powercode) IntelliSense can call attributes very often. ValidateSet with script block becomes similar to ValidateScript (can run unpredictably long).

    Perhaps we should do only IValidateSetGenerator (not script block) because we want support interfaces in PowerShell classes.

    Also could we add IValidateSetGenerator not only in ValidateSet attribute: ValidateScript, ValidatePattern, ... for IntelliSense support?

  7. lfshr commented on May 10, 2017

    @lfshr

    Ilya (@iSazonov) I don't think that would be much of a problem. Most people know not to have long-running commands in intellisense code. People are already working around this issue using the less-friendly dynamicparam block and passing a ValidateSetAttribute to the attribute collection.

    I feel the problem with using an interface for this is that a lot of PowerShell coders aren't programmers. It's one thing to support classes, it's another thing to force the user to use them. Just my opinion ofc. The 'PowerShell way' here is to support a ScriptBlock.

    Jason Shirk (@lzybkr) would the following not be easier:

    public interface IValidateSetGenerator
    {
        IEnumerable<string> Get();
    }
    public class MyValidateSetGenerator : IValidateSetGenerator
    {
        public IEnumerable<string> Get()
        {
            yield return "Something";
        }
    }
    
    [Parameter()]
    [ValidateSet(MyValidateSetGenerator)]
    public string Something { get; set; }

    and just have a ValidateSet overload that takes in an IValidateSetGenerator, rather than using typeof?

  8. lfshr commented on May 10, 2017

    @lfshr

    So two new overloads for ValidateSetAttribute:

    ValidateSetAttribute(ScriptBlock sb)

    and

    ValidateSetAttribute(IValidateSetGenerator g)
  9. iSazonov commented on May 10, 2017

    @iSazonov
    Collaborator

    IValidateSetGenerator vs IValidateSetEnumerator ?

  10. lfshr commented on May 10, 2017

    @lfshr

    Ilya (@iSazonov) maybe even IDynamicValidateSet?

    Edit: Upon reflection I prefer IValidateSetEnumerator

  11. iSazonov commented on May 10, 2017

    @iSazonov
    Collaborator

    It looks like it is from DynamicParams but it is not related directly. Also we have RFC for Dynamic Keywords so we should avoid "Dynamic" term to eliminate confusion.

  12. lzybkr commented on May 10, 2017

    @lzybkr
    ContributorAuthor

    Liam (@lfshr) - C# requires typeof(MyValidateSetGenerator) because MyValidateSetGenerator is not an expression.

    The interface name should probably not end in Enumerator because the interface does not define an enumerator.

  13. iSazonov commented on May 10, 2017

    @iSazonov
    Collaborator

    Maybe IValidateSetValuesGetter

  14. 3 remaining items

  15. oising commented on May 31, 2017

    @oising
    Contributor

    Is this still up for grabs? I'm looking for something small to start with.

    update: never mind, I see the PR is in progress :)

  16. iSazonov commented on Jun 1, 2017

    @iSazonov
    Collaborator

    Welcome to code review!

  17. lordisp commented on Nov 3, 2018

    @lordisp

    maybe you can help me out with my challange. I like to set ValidateSet to run my "example.ps1 -region eu-cental-1" and get the AWS regions

    Eg:
    Param(
    [parameter(Mandatory=$true)]
    [ValidateSet((Get-AWSRegion).region)]
    [String[]]
    $region
    )

    process {
    # do whatever
    }

  18. vexx32 commented on Nov 3, 2018

    @vexx32
    Collaborator

    I don't see any link to the relevant PR, but it appears to need a script block, so you would write:

    [ValidateSet({ (Get-AwsRegion).Region })]
    
  19. lordisp commented on Nov 3, 2018

    @lordisp

    you're right; it's not a PR; just a little script to automate my AWS stuff. Maybe I open one once it has some relevant features.

    [ValidateSet({ (Get-AwsRegion).Region })]

    this does not make any difference unfortunately

  20. vexx32 commented on Nov 3, 2018

    @vexx32
    Collaborator

    Jason Shirk (@lzybkr) a PR is mentioned in this thread, but I don't see any links to it. Did this end up getting implemented?

  21. iSazonov commented on Nov 4, 2018

    @iSazonov
    Collaborator
  22. vexx32 commented on Nov 4, 2018

    @vexx32
    Collaborator

    @rafaelc81 see here for the example that was merged into documentation after the PR was merged.

    https://github.com/PowerShell/PowerShell-Docs/pull/3133/files?short_path=8b392e6#diff-8b392e69e97629458a3c80ee54386057

  23. OlsonDev commented on Jan 14, 2019

    @OlsonDev

    The example in the docs looks nothing like the example the OP of this issue wanted. The OP asks for a script block, and the solution provided is a full on syntax-verbose class.

    I can't get an example like the script block to work. Was that implemented or only the syntax-verbose class version?

    If not, are there any plans to support the significantly more terse syntax? Should another issue be opened?

    Thanks!

  24. iSazonov commented on Jan 15, 2019

    @iSazonov
    Collaborator

    Josh Olson (@OlsonDev) The issue description is misleading. We only implemented a variant based on IValidateSetValuesGenerator interface until we receive more feedback. Feel free open new issue with the description of the necessary feature.

  25. vexx32 commented on Jan 15, 2019

    @vexx32
    Collaborator

    Indeed. It should be possible to borrow portions of the code from [ArgumentCompleter()] for this purpose; it also takes a script block and apparently applies it to the method defined in IArgumentCompleter

  26. iSazonov commented on Jan 15, 2019

    @iSazonov
    Collaborator

    Rain Sallow (/u/ta11ow) (@vexx32) There is samples in attributes.cs file how to use execution context. I assume that the tests will be most of this work and not the code itself. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Issue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributorsWG-Enginecore PowerShell engine, interpreter, and runtime

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions