0

一般に、リソースのリークを避けるために、破棄PSCmdletを実装して必要とする型のパラメーターを取るを作成しようとしています。IDisposeableそのパラメータの も受け入れて、stringその型のインスタンスを作成したいと思いますが、そのオブジェクトを自分で作成した場合は、 から戻る前に破棄する必要がありProcessRecordます。

ArgumentTransformationAttribute文字列からオブジェクトを構築するためにパラメータを使用していますが、オブジェクトを作成したかどうかについてIDisposeable、そのクラスからデータを渡す方法が見つかりませPSCmdletん。例えば:

[Cmdlet("Get", "MyDisposeableName")]
public class GetMyDisposeableNameCommand : PSCmdlet
{
    [Parameter(Mandatory = true, Position = 0), MyDisposeableTransformation]
    public MyDisposeable MyDisposeable
    {
        get;
        set;
    }

    protected override void ProcessRecord()
    {
        try
        {
            WriteObject(MyDisposeable.Name);
        }
        finally
        {
            /* Should only dispose MyDisposeable if we created it... */
            MyDisposeable.Dispose();
        }
    }
}

class MyDisposeableTransformationAttribute : ArgumentTransformationAttribute
{
    public override Object Transform(EngineIntrinsics engineIntrinsics, Object input)
    {
        if (input is PSObject && ((PSObject)input).BaseObject is MyDisposeable)
        {
            /* We were passed a MyDisposeable, we should not dispose it */
            return ((PSObject)input).BaseObject;
        }

        /* We created a MyDisposeable, we *should* dispose it */
        return new MyDisposeable(input.ToString());
    }
}

ここでの私の最善の推測は、MyDisposeableClass明示的な破棄が必要であることをタグ付けするためだけに my をサブクラス化することですが、それはかなりハックに思えます。この場合は機能しますが、シールされたクラスを処理したい場合は明らかに機能しません。

これを行うより良い方法はありますか?

4

2 に答える 2

0

In the end, I simply use parameters that accept a type that wraps MyDisposeable. My initial concern with doing this was that using an internal type for a parameter would impact the functions accessibility. (Perhaps it would negatively impact documentation, but in a cmdlet the documentation is wholly controlled by an XML file.)

After some testing, there do not appear to be any problems using an internal class for a parameter and just letting the transformation accept public types. So I simply create a wrapper class:

public class MyDisposeableWrapper
{
    public MyDisposeable MyDisposeable
    {
        get;
        set;
    }

    public bool NeedsDisposed
    {
        get;
        set;
    }

    public MyDisposeableWrapper(MyDisposeable myDisposeable, bool needsDisposed)
    {
        MyDisposeable = myDisposeable;
        NeedsDisposed = needsDisposed;
    }
}

And have the parameter take that instead. In the transformation attribute, simply set NeedsDisposed based on whether the parameter took a MyDisposeable or constructed one. eg:

if(input is MyDisposeable)
{
    return new MyDisposeableWrapper((MyDisposeable) input, false);
}
else
{
    /* construct MyDisposeable from the input */
    return new MyDisposeableWrapper(myDisposeable, true);
}
于 2012-02-27T15:40:54.987 に答える
0

サブクラス化するのではなく、プロパティを MyDisposable クラスに追加できますか?

public class MyDisposable
{
    ...   
    public bool IsAttributeCreated { get; set; }
}

次に、属性コードで

/* We created a MyDisposeable, we *should* dispose it */
return new MyDisposeable(input.ToString()){IsAttributeCreated=true};

最後にあなたの最終ブロックで

finally
{
    /* Should only dispose MyDisposeable if we created it... */
    if (MyDisposable.IsAttributeCreated)
        MyDisposeable.Dispose();
}
于 2012-02-18T18:09:52.967 に答える