8

When exposing a set of related functions in Powershell cmdlets, is it possible to share the property names and summary help to normalize these across cmdlets in an assembly?

I know that this can be done with derived classes, but this solution is awkward at best when there are multiple cmdlets with different properties to be shared.

Here is an extremely simple example. I would like to share the property 'Name' and all related comments so that they are the same across the N cmdlets we are producing, but I cannot think of a good way to do this in c#. Ideally any sharing would allow specification of Parameter attributes such as Mandatory or Position.

namespace FrozCmdlets
{
using System.Management.Automation;

/// <summary>
/// Adds a new froz to the system.
/// </summary>
[Cmdlet( VerbsCommon.Add, "Froz" )]
public class AddFroz : Cmdlet
{
    /// <summary>
    /// The name of the froz.
    /// For more information on the froz, see froz help manual.
    /// </summary>
    [Parameter]
    public string Name { get; set; }

    protected override void ProcessRecord()
    {
        base.ProcessRecord();
        // Add the froz here
    }
}

/// <summary>
/// Removes a froz from the system.
/// </summary>
[Cmdlet( VerbsCommon.Remove, "Froz" )]
public class RemoveFroz : Cmdlet
{
    /// <summary>
    /// The name of the froz.
    /// For more information on the froz, see froz help manual.
    /// </summary>
    [Parameter]
    public string Name { get; set; }

    protected override void ProcessRecord()
    {
        base.ProcessRecord();
        // Remove the froz here
    }
}
}
pennyowe
  • 165
  • 7
  • If you do not want to derive (I'm not clear about the reason) the best way to share comments is to use XML includes (look at framework source code). You keep code documentation outside your code, it can be written and maintained (if needed) by someone else and it can be shared across classes and even assemblies. – Adriano Repetti Jun 28 '12 at 23:07
  • @Adriano Thanks for the idea to look at sharing comments via XML includes. The reasoning behind not wanting to derive is that it's possible to do cleanly. If cmdlet A uses P1, P2 while cmdlet B uses P2, P3 and cmdlet C uses P1, P3 there is no way to derive and share P1, P2, P3 as desired. I realize also that my idea of sharing these properties may not be well-founded. It has just become a hassle to update the N places whenever something changes and I sure do hate copy and pasted code. – pennyowe Jun 29 '12 at 00:08
  • Oh, then you're right! I just thought they had many shared properties. Only way I think to do it is via include (but it's OK only for comments). Someday (maybe...) we'll have multiple inheritance... – Adriano Repetti Jun 29 '12 at 07:23
  • 1
    And what about creating sets of properties via interface (they can define methods or properties). This is the way to 'simulate' multiple inheritance. Idon't know if in your case it can do the trick. – JPBlanc Jun 29 '12 at 11:20

1 Answers1

3

Yes, there is a way to do this without inheriting from a common base class for the parameters. Its not not well documented, only hinted at in the IDynamicParameters.GetDynamicParameters method's remarks. Here's a more detailed treatment of the topic.

First, create a class with your common parameters declared as properties with the [Parameter] attributes:

internal class MyCommonParmeters
{
    [Parameter] 
    public string Foo { get; set; }
    [Parameter]
    public int Bar { get; set; }
    ...
}

Then each Cmdlet that wants to use these common parameters should implement the IDynamicParameters interface to return a member instance of the MyCommonParameters class:

[Cmdlet(VerbsCommon.Add, "Froz")]
public class AddFroz : PSCmdlet, IDynamicParameters
{
    private MyCommonParmeters MyCommonParameters 
        = new MyCommonParmeters();

    object IDynamicParameters.GetDynamicParameters()
    {
        return this.MyCommonParameters;
    }
    ...

With this approach, the PowerShell command parameter binder will find and populate the parameters on the MyCommonParameters instance just as if they were members of the Cmdlet classes.

Burt_Harris
  • 6,415
  • 2
  • 29
  • 64
  • Very cool - thanks Burt! I haven't had a chance yet to try this but it seems like it will fit the billing. – pennyowe Jul 16 '14 at 16:26