views:

184

answers:

1

Is it possible to use Dependency Injection (DI) with Windows PowerShell?

My intitial experiments suggest that it isn't. If I attempt to use Constructor Injection in a CmdLet it doesn't even register itself. In other words, this is not possible:

[Cmdlet(VerbsDiagnostic.Test, "Ploeh")]
public class PloehCmdlet : Cmdlet
{
    public PloehCmdlet(IFoo foo)
    {
        if (foo == null)
        {
            throw new ArgumentNullException("foo");
        }

        // save foo for later use
    }

    protected override void ProcessRecord()
    {
        this.WriteObject("Ploeh");
    }
}

If I add a default constructor, the CmdLet can be registered and used, but without the default constructor, it's simply not available.

I know I could use a Service Locator to retrieve my dependencies, but I consider that an anti-pattern so don't want to go that way.

I would have hoped that the PowerShell API had some kind of 'Factory' hook similar to WCF's ServiceHostFactory, but if there is, I can't find it.

+1  A: 

An instance of the cmdlet class is created from an empty constructor every time the cmdlet is used in PowerShell. You have no control over which constructor PowerShell will pick, so you cannot do what you are proposing in a straightforward way (and I really have a hard time imagining why you would want to). So the simple answer to this question is NO.

To acheive a similar affect, you can make an interface that looks like a cmdlet (has BeginProcessing/EndProcessing/ProcessRecord/StopProcessing) and use to populate a bunch of cmdlets that are thin wrappers over the real code. IMHO this would be an overcomplicated approach.

I really don't see why you are trying to do this. Could you explain a little more about the scenario?

Start-Automating
Testability would be my main reason, but any reason to use DI applies equally well to Cmdlets - why should they be different than the rest of my code?
Mark Seemann