Динамическое определение класса в Командлете 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.