我从数据源获取了一些数据,这是一组名称/值对,我存储在Dictionary< string,object>中。
我想动态定义一个类,其属性映射到字典中的键/值对,以及基于它所代表的数据类型的方法。这将允许cmdlet的用户作为对象的属性访问值,并在其上调用方法。
我用Get-WmiObject看到了这个例子。它返回ManagementObject的实例(基本上是一个通用属性包),但用户可以直接访问属性并在其上调用方法(即无需在ManagementObject上调用GetPropertyValue / InvokeMethod方法)。
PS C:\temp> $comp = Get-WmiObject Win32_ComputerSystem
PS C:\temp> $comp | Get-Member
TypeName: System.Management.ManagementObject#root\cimv2\Win32_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 ...
如何使用自己的对象执行此操作?
更新
接受Keith的答案,这是一种动态生成代码的通用.NET框架方法。这应该适用于我的场景,虽然我认为它可能有点过分。
我希望有人能够使用PowerShell提供的功能提供一个明确的示例。似乎应该有一种通过扩展PSObject中描述的PSProperty,PSMethod和Powershell SDK类来动态创建类的方法。
不幸的是,围绕这个的文档看起来很糟糕,有许多荒谬的陈述,如“虽然可以从这个类派生,但是没有确定的方法可以做到这一点,任何这样做的尝试都可能导致意外行为。“
更糟糕的是MSDN中解释PowerShell扩展类型系统的所有链接似乎都很糟糕!我在网上看到的唯一例子是如何从PowerShell脚本执行此操作,而不是使用C#和SDK开发cmdlet的人。
您好,PowerShell团队的任何人都在听吗?
答案 0 :(得分:6)
定义自己的新类的能力是他们在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” - 通常这是为了生成用于传递给cmdlet或函数的名称/值对,但它可以作为通用的一种工作各种对象:
PS C:\> $splat = @{
Name = "goyuix"
Site = "stackoverflow.com"
Tag = "powershell"
}
PS H:\> $splat
Name Value
---- -----
Name Goyuix
Site stackoverflow.com
Tag powershell
答案 1 :(得分:3)
看看System.Reflection.Emit namespace。这将允许您在运行时生成代码。 System.AppDomain有许多名为DefineDynamicAssembly
的重载,通常是您要启动的地方。这会返回AssemblyBuilder
,您可以使用TypeBuilder
,PropertyBuilder
,MethodBuilder
等类型。CodeProject article是创建动态类型的理想入门读物反射发射。
答案 2 :(得分:0)
我一直致力于增强PSClass的实现。
实施来源: https://github.com/ghostsquad/AetherClass/blob/master/functions/New-PSClass.ps1
测试用法: https://github.com/ghostsquad/AetherClass/blob/master/test/New-PSClass.Tests.ps1
还有模拟psclass的功能,也就是说,你可以使用动态psobject获得Moq的所有漂亮功能。