开发者

How to dynamically define a class in C# PowerShell Cmdlet

I have some data I'm getting from a datasource which is a bunch of name/value pairs that I store in a Dictionary<string, object>.

I want to define a class on the fly, with properties that map to the key/value pairs from the dictionary and methods based on the type of data it represents. This would allow the user of the cmdlet to access the values as properties of an object and also invoke methods on it.

I see an example of this with Get-WmiObject. It returns instances of ManagementObject (which is basically a generic property bag) but the user is able to access the properties and invoke methods on it directly (i.e. without having to call the GetPropertyValue/InvokeMethod methods on ManagementObject).

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 ...

How do I do this with my own objects?

UPDATE

Accepting Keith's answer which is a general .NET framework approach for generating code dynamically. This should work for my scenario although I think it might be overkill.

I was hopin开发者_如何学Pythong someone would provide a clear example of doing this using the facilities provided by PowerShell. It seems there should be a way to create a class dynamically by extending the PSObject, PSProperty, and PSMethod classes described in the Powershell SDK.

Unfortunately the documentation around this seems pretty poor with a lot of ridiculous statements like "Although it is possible to derive from this class, there is no established scenario for doing this and any attempt to do so may result in unexpected behavior."

What made it worse is that all the links in MSDN explaining the PowerShell Extended Type System seem to be bad! And the only examples I've seen on the web is how to do this from a PowerShell script, not for people developing cmdlets using C# and the SDK.

Hello, anyone from the PowerShell team listening?


The ability to define your own new classes is something new they added in PowerShell v2. Here is a sample:

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

If you don't need something too complex, you might be able to take advantage of "splatting" - typically this is for producing name/value pairs for passing to cmdlets or functions, but it can work as kind of a generic object of sorts too:

PS C:\> $splat = @{
  Name = "goyuix"
  Site = "stackoverflow.com"
  Tag = "powershell"
}

PS H:\> $splat

Name    Value
----    -----
Name    Goyuix
Site    stackoverflow.com
Tag     powershell


Take a look at the System.Reflection.Emit namespace. This will allow you to generate code at runtime. System.AppDomain has a number of overloads called DefineDynamicAssembly which is typically where you would start. This returns an AssemblyBuilder and from there you use types like TypeBuilder, PropertyBuilder, MethodBuilder, etc. This CodeProject article is a decent primer on creating dynamic types with reflection emit.


I've been working on enhancing an implementation of PSClass.

Implementation source: https://github.com/ghostsquad/AetherClass/blob/master/functions/New-PSClass.ps1

Tests with usage: https://github.com/ghostsquad/AetherClass/blob/master/test/New-PSClass.Tests.ps1

There's also functionality to mock psclasses, which is to say, you get all the nifty functionality of Moq with a dynamic psobject.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜