src/cmdlet/Invoke-Method.ps1
# Copyright 2019, Adam Edwards # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Invoke-Method { [cmdletbinding()] param( [Parameter(mandatory=$true)] $Context, [Parameter(mandatory=$true)] $Action, [Parameter(valuefromremainingarguments=$true)] [object[]] $Arguments ) if ( $Context -eq $null ) { throw "Invalid Context -- Context may not be `$null" } if ( $Action -eq $null ) { throw "Invalid Action argument -- Action may not be `$null" } if ( $Action -isnot [string] -and $Action -isnot [ScriptBlock] ) { throw [ArgumentException]::new("The specified Action argument of type '$($Action.GetType())' must be of type [String] or type [ScriptBlock]") } $isExtendedClass = Test-ScriptObject $Context if ( $isExtendedClass ) { $invocationMethods = [ScriptClassSpecification]::Parameters.Schema if ( $Action -is [string] ) { $Context.$($invocationMethods.InvokeMethodMethodName)($Action, $arguments) } else { # TODO: Should this rebinding be an optional capability for InvokeScriptMethod? $boundScript = ($Context.psobject.methods | where name -eq $invocationMethods.InvokeScriptMethodName).script.module.newboundscriptblock($Action) $Context.$($invocationMethods.InvokeScriptMethodName)($boundScript, $arguments) } } else { if ( $Action -is [string] ) { throw [ArgumentException]::new("Object is not a '$([ScriptClassSpecification]::Parameters.TypeSystemName)' extended type system object") } $objectMethodsAsfunctions = @{} $Context.psobject.members | foreach { if ( $_.membertype -eq 'ScriptMethod' ) { $objectMethodsAsfunctions[$_.name] = $_.value.script } } $thisVariable = [PSVariable]::new('this', $Context) $Action.InvokeWithContext($objectMethodsAsFunctions, $thisVariable, $arguments) } } |