tags:

views:

39

answers:

2

I define a custom PowerShell type with New-Object. I would like a parameter to be of my defined type, is it possible to specify this type in a declarative way? The following code gives me the error: "Unable to find type [BuildActionContext]: make sure that the assembly containing this type is loaded."

Can we specify the type declarative, or should I just test the type of the specified object?

Not working code:

$buildActionContext = New-Object -TypeName PSObject -Property @{
# Given properties
BuildAction = "Build"; 
}
$buildActionContext.PSObject.TypeNames.Insert(0, 'BuildActionContext')

function DoSomethingWithBuildActionContext
{
[CmdletBinding()]
param
(
    [Parameter(Mandatory=$true)][BuildActionContext]$Context
)

Write-Host "Build action: $($Context.BuildAction)"
}

DoSomethingWithBuildActionContext -Context $buildActionContext

Working code, but can it be done differently:

$buildActionContext = New-Object -TypeName PSObject -Property @{
        # Given properties
        BuildAction = "Build"; 
    }
    $buildActionContext.PSObject.TypeNames.Insert(0, 'BuildActionContext')

function DoSomethingWithBuildActionContext
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true)]$Context
    )

    if ($Context.PSObject.TypeNames[0] -ne 'BuildActionContext')
    {
        throw "Context parameter not of type 'BuildActionContext'"
    }

    Write-Host "Build action: $($Context.BuildAction)"
}

DoSomethingWithBuildActionContext -Context $buildActionContext
DoSomethingWithBuildActionContext -Context "Hello world"

Note: Second call gives the exception message.

A: 

Great question. I tried

$buildActionContext -is [BuildActionContext]

And get

Unable to find type [BuildActionContext]: make sure that the assembly containing this type is loaded.

Which is the error you get in the first example. Off the top of my head I would want to create a C# object for that type but that is probably overkill.

I'll keep searching.

Doug Finke
+3  A: 

I would expect that only real .NET types can be used to specify parameter type. According to Essential PowerShell: Name your custom object types the custom type names are mainly used for formatting.

If you will check the type names manually, you can use attributes for that:

function DoSomethingWithBuildActionContext { 
  param(
    [Parameter()]
    [ValidateScript({ $_.PSObject.TypeNames[0] -eq 'BuildActionContext' })]
    $context
  )
  Write-Host "Build action: $($Context.BuildAction)"
}
stej
Right, New-Object does not create types, it creates instances of types. You can use Add-Type to create a type with C# or VB.NET.
JasonMArcher