2012-02-17 109 views
0

通常,我试图创建一个PSCmdlet,该参数需要实现IDisposeable的类型的参数,并且需要处理以避免资源泄漏。我还想接受该参数的string并创建该类型的实例,但是如果我自己创建该对象,那么我需要在从ProcessRecord返回之前处理它。从其参数传递属性传递数据到PSCmdlet

为了从字符串建立我IDisposeable对象我使用的是我的参数的ArgumentTransformationAttribute,但我找不到任何方式从该类数据传递给我的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只是标签,它需要明确的处置,但似乎相当哈克,而它的工作原理在这种情况下,它显然不会,如果我的工作想要处理一个密封的课程。

有没有更好的方法来做到这一点?

回答

0

最后,我简单地使用接受包装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); 
} 
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块

finally 
{ 
    /* Should only dispose MyDisposeable if we created it... */ 
    if (MyDisposable.IsAttributeCreated) 
     MyDisposeable.Dispose(); 
} 
+0

不幸的是,在这种情况下,“MyDisposeable”来自一个我无法修改的库,缺少一些反思。 – 2012-02-18 21:42:20