Динамическое определение класса в Командлете C# PowerShell
У меня есть некоторые данные, которые я получаю из источника данных, который представляет собой кучу пар имя/значение, которые я храню в словаре.
Я хочу определить класс на лету, со свойствами, которые сопоставляются парам ключ / значение из словаря и методов, основанных на типе данных, которые он представляет. Это позволит пользователю командлета для доступа к значениям свойств объекта, а также вызывать методы на нем.
Я вижу пример этого с Get-WmiObject. Он возвращает экземпляры ManagementObject (который в основном является общим пакетом свойств), но пользователь может получить доступ к свойствам и вызывать методы на нем напрямую (т. е. без вызова методов GetPropertyValue/InvokeMethod на ManagementObject).
PS C:temp> $comp = Get-WmiObject Win32_ComputerSystem
PS C:temp> $comp | Get-Member
TypeName: System.Management.ManagementObject#rootcimv2Win32_ComputerSystem
Name MemberType Definition
---- ---------- ----------
JoinDomainOrWorkgroup Method System.Management.ManagementBaseObject JoinDomainO
Rename Method System.Management.ManagementBaseObject Rename(Syst
SetPowerState Method System.Management.ManagementBaseObject SetPowerSta
UnjoinDomainOrWorkgroup Method System.Management.ManagementBaseObject UnjoinDomai
AdminPasswordStatus Property System.UInt16 AdminPasswordStatus {get;set;}
AutomaticManagedPagefile Property System.Boolean AutomaticManagedPagefile {get;set;}
AutomaticResetBootOption Property System.Boolean AutomaticResetBootOption {get;set;}
... etc ...
Как это сделать с моими собственными объектами?
обновление
принятие ответа кита, который является общим подходом .NET framework для динамического создания кода. Это должно работать по моему сценарию, хотя я думаю, что это может быть перебор.
Я надеялся, что кто-то предоставит четкий пример этого, используя возможности, предоставляемые PowerShell. Кажется, должен быть способ создать класс динамически путем расширения PSObject, PSProperty и PSMethod классы, описанные в Powershell SDK.
к сожалению, документация вокруг этого кажется довольно плохой с много нелепых утверждений типа "хотя можно вывести из этого класса, нет установленного сценария для этого, и любая попытка сделать это может привести к неожиданному поведению."
хуже всего то, что все ссылки в MSDN, объясняющие систему расширенного типа PowerShell, кажутся плохими! И единственные примеры, которые я видел в интернете, - это как это сделать из сценария PowerShell, а не для людей, разрабатывающих командлеты с помощью C# и пакет SDK.
Здравствуйте, кто-нибудь из команды PowerShell слушает?
3 ответов
возможность определять свои собственные новые классы-это что-то новое, что они добавили в PowerShell v2. Вот пример:
PS C:\> $def = @"
public class MyClass {
public string MyProperty;
}
"@
PS C:\> Add-Type -TypeDefinition $def
PS C:\> $obj = New-Object MyClass
PS C:\> $obj.MyProperty = "Hello"
PS C:\> $obj
MyProperty
----------
Hello
Если вам не нужно что - то слишком сложное, вы можете воспользоваться "splatting" - обычно это для создания пар имя / значение для передачи командлетам или функциям, но он может работать как своего рода общий объект тоже:
PS C:\> $splat = @{
Name = "goyuix"
Site = "stackoverflow.com"
Tag = "powershell"
}
PS H:\> $splat
Name Value
---- -----
Name Goyuix
Site stackoverflow.com
Tag powershell
Я работал над улучшением реализации PSClass.
источник реализации : https://github.com/ghostsquad/AetherClass/blob/master/functions/New-PSClass.ps1
тесты с использованием: https://github.com/ghostsquad/AetherClass/blob/master/test/New-PSClass.Tests.ps1
есть также функциональность для макета psclasses, то есть вы получаете все изящные функции Moq с динамическим psobject.