Tuesday 3 July 2012

PowerShell–Object Orientation

PowerShell does not have a class construct as a first class citizen. You can create objects either from .NET or creating CmdLets but how do you create an object from a pure PowerShell script?.

I came up with a solution previously I would like to share. However doing a bit of searching afterwards I found this project on CodePlex The solution looks pretty awesome so it is probably worth checking out as well.

The solution I came up with previously was to use PSObject and using Add-Member Cmdlet.

I wanted to be able to describe the function that I will be using as follows:

PowerShell Object Builder Definition
1
2
3
function New-ObjectBuilder()
{
}

You would use this as follows:

PowerShell Object Builder Usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function New-MyObject()
{   
    $obj = New-ObjectBuilder
    $obj.AddBackingField("_Test", "testing")
    $obj.AddProperty("Test", [ref]$obj._Test)
    $obj.AddMethod("TestRun", {
        param ($aaa, $bbb)
        Write-Host "TestRun: " $this.Test, $aaa, $bbb
  
    });
    return $obj
}
$obj = New-MyObject
$obj.TestRun("a1", "b11")

And there is not really that much code to implement this function:

PowerShell Object Builder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function New-ObjectBuilder()
{
    $instance = new-object PSObject
     
    $instance | add-member -MemberType ScriptMethod -Name AddProperty -Value {
        param ($name, [ref]$backingField)
        $this | add-member -MemberType ScriptProperty -Name $name -Value {
            return $backingField.Value
        }.GetNewClosure() -SecondValue {
            $backingField.Value = $args[0]
        }.GetNewClosure()  
    }
     
    $instance | add-member -MemberType ScriptMethod -Name AddBackingField -Value {
        param ($name, $value = '')
        $this = Add-Member -InputObject $this -MemberType NoteProperty -Name $name -Value $value -PassThru
    }
 
    $instance | add-member -MemberType ScriptMethod -Name AddMethod -Value {
        param ($name, $codeBlock)
        $this | add-member -MemberType ScriptMethod -Name $name -Value $codeBlock
    }
     
    return $instance
}

You can now reuse this function and create new functions to construct your object

No comments:

Post a Comment