Extract the logic in a seperate class and call it directly. Use the cmdlet to be, well, just a shell around this new class.
This Seperation of Concerns (SoC) also enables easier unit tests and leads to an overall cleaner architecture.
Extracted Class Greeter.cs
public class Greeter {
public Greeter(string name) {
_Name = name;
}
private string _Name;
public string SayHello() {
return $"Hello {_Name}";
}
public string SayGoodBye() {
return $"So long {_Name}, and thanks for all the fish!";
}
}
CommandLet GetGreetingCommand.cs
[Cmdlet("Greeting", "Get")]
public class GetGreetingCommand : Cmdlet {
[Parameter(Mandatory = true)]
public string Name { get; set; }
protected override void ProcessRecord() {
var greeter = new Greeter(Name);
var greeting = greeter.SayHello();
WriteObject(greeting);
}
}
CommandLet GetGoodByeCommand .cs
[Cmdlet("GoodBye", "Get")]
public class GetGoodByeCommand : Cmdlet {
[Parameter(Mandatory = true)]
public string Name { get; set; }
protected override void ProcessRecord() {
var greeter = new Greeter(Name);
var goodBye = greeter.SayGoodBye();
WriteObject(goodBye);
}
}
Console Main.cs (or any other client-code of Greeter-class)
public static void main(string[] args) {
var greeter = new Greeter(args.FirstOrDefault());
Console.WriteLine(greeter.SayHello());
Console.WriteLine(greeter.SayGoodBye());
}
TestCase
public static void SayingHelloUsesName() {
var sut = new Greeter("Arthur");
var expected = "Hello Arthur";
var actual = sut.SayHello();
Assert.AreEqual(expected, actual);
}
The two concerns here are
- the actual BusinessLogic (Greeter.cs)
- interoperability with PowerShell, providing mechanisms to parameterize the cmdlet, etc. (Get*Command.cs). As you see, the cmdlets really only pass through the calls, while enabling use via PowerShell.
@Mathias R. Jessen ´ answer could be usefull, if you need to call third party cmdlets, but in most cases, there should be an appropriate (non-powershell) API for what you are trying to do.