将数据从其 ArgumentTransformationAttribute 传递给 PSCmdlet
本文关键字:PSCmdlet ArgumentTransformationAttribute 数据 | 更新日期: 2023-09-27 18:24:56
通常,我正在尝试创建一个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
子类化只是为了标记它需要显式处置,但这似乎相当笨拙,虽然它在这种情况下有效,但如果我想处理密封类,它显然不起作用。
有没有更好的方法可以做到这一点?
除了子类化,你能把一个属性添加到你的 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();
}
最后,我只是使用接受包装MyDisposeable
的类型的参数。 我最初担心的是,对参数使用内部类型会影响函数的可访问性。 (也许这会对文档产生负面影响,但在 cmdlet 中,文档完全由 XML 文件控制。
经过一些测试,使用内部类作为参数并仅让转换接受公共类型似乎没有任何问题。 所以我简单地创建了一个包装类:
public class MyDisposeableWrapper
{
public MyDisposeable MyDisposeable
{
get;
set;
}
public bool NeedsDisposed
{
get;
set;
}
public MyDisposeableWrapper(MyDisposeable myDisposeable, bool needsDisposed)
{
MyDisposeable = myDisposeable;
NeedsDisposed = needsDisposed;
}
}
并让参数取而代之。 在转换属性中,只需根据参数是采用MyDisposeable
还是构造参数来设置NeedsDisposed
。 例如:
if(input is MyDisposeable)
{
return new MyDisposeableWrapper((MyDisposeable) input, false);
}
else
{
/* construct MyDisposeable from the input */
return new MyDisposeableWrapper(myDisposeable, true);
}