Reputation: 4732
I am building an automation system using Powershell and I would like to define custom .Net types so that I can structure my application in a similar way to the other code I write.
At first, I tried using ‘Add-Type’ to import types from c# files into my application but I found this to be extremely painful to debug as a .net type can only be loaded once during per Powershell session. This means that when there are errors a single change to my code requires me to restart my app (I might as well be using C#).
At the moment I am simulating types in Powershell by using factory functions that dynamically generate PSObjects with the semantics I need. This does work but it is very verbose and I don’t seem to be able to declare private variables or methods for encapsulation.
Is there an easier way to achieve what I want?
If not....
Am I somehow barking up the wrong tree by wanting to write my Powershell code using abstract data types?
Is there a better way to structure my system that I should know about?
Can I achieve some encapsulation with what I am doing now?
Upvotes: 2
Views: 503
Reputation: 29459
1) I haven't tried it, but this project looks promising: PSClass - Object Oriented Scripting in Powershell. Some features it offers:
PsClass is currently implemented in Powershell in a single file. Makes it simple to use. It supports the following OO concepts.
- Inheritance
- Polymorphism
- Encapsulation
- Constructors with parameters
- Notes – read-write variables
- Methods – scriptblocks
- Properties with Get scriptblocks and optional Set scriptblocks
- Static and Private Notes and Methods
2) You could use custom modules like this:
$o = New-Module -AsCustomObject -Function GetVar, AddToVar {
$script:var = 1
function checkRange { if ($var -gt 3 -or $var -lt 0) { throw 'not in range <0,3>' } }
function GetVar { $script:var }
function AddToVar { param($add) checkRange; $script:var += $add; $script:var }
}
$o.GetVar()
$o.AddToVar(2)
$o.AddToVar(1)
$o.GetVar()
$o.checkRange()
$o | gm
Try to copy it to your ide/console and run it. $script:var
is private member that can be used only from functions GetVar
,AddToVar
. checkRange
is private as well.
Personally I wouldn't use PowerShell for such a task if I needed real OOP (available in C#). PowerShell has some support for objects, but very poor for OOP.
Upvotes: 2