PSVersion: 5.1
Desired
What I wished would work$obj = [PSCustomObject]@{
PSTypeName = 'MyObject'
con = 'local'
}
add-member -MemberType ScriptMethod -InputObject $obj -Name MyMethod -Value {
param([parameter(ValueFromPipeline=$true)]$x)
begin {write-host 'begin'}
process{write-host "$($this.con): $x"}
end {write-host 'end'}
}
1..5 | $obj.MyMethod
To give
begin
local: 1
local: 2
local: 3
local: 4
local: 5
end
but gives error
At line:1 char:8
+ 1..5 | $obj.MyMethod
+ ~~~~~~~~~~~~~
Expressions are only allowed as the first element of a pipeline.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
Tried
what doesn't work because: idk, tl;dr reasons?1..5 | %{$obj.MyMethod($_)}
what doesn't work because: begin/end
$obj = [PSCustomObject]@{
PSTypeName = 'MyObject'
con = 'local'
}
add-member -MemberType ScriptMethod -InputObject $obj -Name MyMethod -Value {
param($x)
write-host "$($this.con): $x"
}
1..5 | %{$obj.MyMethod($_)}
what doesn't work because: $this is no longer attached
$obj = [PSCustomObject]@{
PSTypeName = 'MyObject'
con = 'local'
MyMethodSB = {
param()
begin {write-host 'begin'}
process{write-host "$($obj.con): $_"}
end {write-host 'end'}
}
}
1..5 | &$obj.MyMethodSB
what doesn't work because: idk, maybe the scope of Stepper dies prematurely
$obj = [PSCustomObject]@{
PSTypeName = 'MyObject'
con = 'local'
Stepper = $null
}
add-member -MemberType ScriptMethod -InputObject $obj -Name MyMethod -Value {
param($x)
if($null -eq $this.Stepper){
$t = $this
$sb = {
param($o)
begin {write-host 'begin'}
process{write-host "$($o.con): $_"}
end {write-host 'end'}
}
$this.Stepper = {&$sb $t}.GetSteppablePipeline()
$this.Stepper.Begin($true)
}
$this.Stepper.Process($x)
}
1..5 | %{$obj.MyMethod($_)}
$obj.Stepper.End()
$obj.Stepper = $null
Almost There
What is kinda working$Data = @{
ItemNo1 = @(
@{loc = 'WH'; qty = 20}
@{loc = 'DK'; qty = 0}
@{loc = 'ST1'; qty = 3}
@{loc = 'ST2'; qty = 2}
)
ItemNo2 = @(
@{loc = 'WH'; qty = 6}
@{loc = 'DK'; qty = 0}
)
ItemNo3 = @(
@{loc = 'WH'; qty = 100}
@{loc = 'ST1'; qty = 5}
@{loc = 'DK'; qty = 0}
)
ItemNo4 = @(
@{loc = 'WH'; qty = 0}
@{loc = 'DK'; qty = 0}
@{loc = 'ST2'; qty = 15}
)
ItemNo5 = @(
@{loc = 'WH'; qty = 0}
@{loc = 'DK'; qty = 15}
)
}
$QueryParameter = [PSCustomObject]@{Value = $null}
function MockDataQuery{
$Item = $QueryParameter.Value
foreach($iDat in $Data.$Item){
" $Item;$($iDat.loc);$($iDat.qty)"
}
}
$InvObj = [PSCustomObject]@{
PSTypeName = 'Data.Connection'
con = 'item.inventory'
}
add-member -MemberType ScriptMethod -InputObject $InvObj -Name FetchItemData -Value {
$p = $this
$qPipe = [PSCustomObject]@{
PSTypeName = 'Data.Connection.QueryPipe'
parent = $p
qHeader = 'Item;Location;Quantity'
query = 'select * from inventory where item = ?'
param = $null
}
add-member -MemberType ScriptMethod -InputObject $qPipe -Name begin -Value {
param([bool]$Header=$true)
write-host "connect to: $($this.parent.con)"
write-host "compile command: $($this.query)"
$this.param = $QueryParameter
write-host 'begin transaction'
if($Header){
write-host " $($this.qHeader)"
}
}
add-member -MemberType ScriptMethod -InputObject $qPipe -Name process -Value {
param($itm)
$this.param.Value = $itm
MockDataQuery | write-host
}
add-member -MemberType ScriptMethod -InputObject $qPipe -Name end -Value {
write-host 'end transaction'
write-host 'dispose command'
write-host 'close connection'
}
return $qPipe
}
1..5 | %{"ItemNo$_"} | &{
begin {$stp = $InvObj.FetchItemData();$stp.begin()}
process{$stp.process($_)}
end {$stp.end()}
}
While this seems to be a functional model, it would be better if there was a solution that didn't require the user of the connection object to have to code the begin/process/end script on their end every time they use the object's method.