I realize this isn't likely to apply to OP at this point, but this question was the first result for my search so I'll post what I figured out here.
I'm pretty surprised this one isn't already mentioned, but CodeMethods in PowerShell are essentially compiled extension methods for a given type. They're pretty easy to write, too - especially when you already have the extension method.
public static class MyStringExtensions
{
public static string Append(this string source, params char[] characters)
{
foreach (var c in characters)
{
source += c;
}
return source;
}
// named PSAppend instead of Append. This is just a naming convention I like to use,
// but it seems some difference in name is necessary if you're adding the type data
// via a types.ps1xml file instead of through the Update-TypeData command
public static string PSAppend(PSObject source, params char[] characters)
{
if (source.BaseObject is string sourceString)
{
return sourceString.Append(characters);
}
else throw new PSInvalidOperationException();
}
private static string Example() {
var myString = "Some Value.";
Console.WriteLine(myString.Append(" and then some more.".ToCharArray()));
// console output:
// Some Value. and then some more.
}
}
After loading the type definition into PowerShell:
$method = [MyStringExtensions].GetMethod('PSAppend')
Update-TypeData -TypeName System.String -MemberName Append -MemberType CodeMethod -Value $method
# now you can use the method the same way you'd use an extension method in C#
PS:\> $myString = "Some Value."
PS:\> $myString.Append(" and then some more.")
Some value. and then some more.
Documentation for code methods is less than ideal. If you're building this into a module and defining a CodeMethod in your Types.ps1xml file referenced by your manifest (.psd1), you'll need to include the assembly that defines the code method in the RequiredAssemblies
of the manifest. (Including it as RootModule
is insufficient because the assemblies of the type(s) must be loaded before the type file(s) are loaded.)
Here's how you'd include this type definition in a Types.ps1xml file:
<?xml version="1.0" encoding="utf-8" ?>
<Types>
<Type>
<Name>System.String</Name>
<Members>
<CodeMethod>
<Name>Append</Name>
<CodeReference>
<TypeName>MyStringExtensions</TypeName>
<MethodName>PSAppend</MethodName>
</CodeReference>
</CodeMethod>
</Members>
</Type>
</Types>