在C#中,是否可以在PowerShell cmdlets之间共享属性和注释?

8
当在Powershell cmdlets中公开一组相关函数时,是否可以共享属性名称和摘要帮助以在程序集中规范这些内容?
我知道可以通过派生类来实现此目的,但是当有多个cmdlet需要共享不同属性时,这种解决方案最多只能算是笨拙。
以下是一个极其简单的示例。我想共享属性“Name”及其所有相关注释,使得它们在我们正在生成的N个cmdlet中保持一致,但我无法想到在c#中实现这个目标的好方法。理想情况下,任何共享都应允许指定参数属性,例如Mandatory或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
    }
}
}

如果您不想派生(我不确定原因),共享注释的最佳方式是使用XML包含(查看框架源代码)。您可以将代码文档保留在代码之外,它可以由其他人编写和维护(如果需要),并且可以跨类甚至程序集共享。 - Adriano Repetti
@Adriano 感谢您提供的通过 XML 包含共享注释的想法。不希望派生的原因是可以干净地完成。如果 cmdlet A 使用 P1、P2,而 cmdlet B 使用 P2、P3,cmdlet C 使用 P1、P3,则无法推导和共享所需的 P1、P2、P3。我也意识到,我的共享这些属性的想法可能没有根据。每当有变化时更新 N 个位置已经成为一件麻烦事了,我真的很讨厌复制和粘贴代码。 - pennyowe
噢,那你是对的!我只是以为它们有许多共同的属性而已。我认为唯一的方法是通过包含来实现(但这只适用于注释)。也许有一天,我们会有多重继承... - Adriano Repetti
1
那么通过接口创建属性集合呢(它们可以定义方法或属性)。这是“模拟”多重继承的方法。我不知道在你的情况下是否可行。 - JPBlanc
1个回答

3
是的,有一种方法可以在不继承参数的共同基类的情况下实现此操作。它并没有得到很好的文档支持,在IDynamicParameters.GetDynamicParameters方法的备注中仅仅是暗示。以下是这个主题的更详细论述。
首先,创建一个类,将您的公共参数声明为属性,并使用[Parameter]属性:
internal class MyCommonParmeters
{
    [Parameter] 
    public string Foo { get; set; }
    [Parameter]
    public int Bar { get; set; }
    ...
}

接下来,希望使用这些公共参数的每个Cmdlet都应该实现IDynamicParameters接口,以返回MyCommonParameters类的成员实例:

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

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

使用这种方法,PowerShell命令参数绑定程序将像成员变量一样查找和填充MyCommonParameters实例上的参数,而不需要在Cmdlet类中定义它们。

非常酷 - 谢谢Burt!我还没有机会尝试这个,但它似乎很适合。 - pennyowe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接