تمرير البيانات إلى PSCmdlet من ArgumentTransformationAttribute الخاص بها

StackOverflow https://stackoverflow.com/questions/9335277

  •  27-10-2019
  •  | 
  •  

سؤال

بشكل عام، أحاول إنشاء ملف PSCmdlet يأخذ معلمة من النوع الذي يتم تنفيذه IDisposeable ويتطلب التخلص منها لتجنب تسرب الموارد.أود أيضًا أن أقبل أ string لهذه المعلمة وإنشاء مثيل من هذا النوع، ولكن إذا قمت بإنشاء هذا الكائن بنفسي، فسأحتاج إلى التخلص منه قبل العودة من ProcessRecord.

أنا أستخدم ArgumentTransformationAttribute مع المعلمة الخاصة بي من أجل بناء ملفي IDisposeable كائن من سلسلة، ولكن لا يمكنني العثور على أي طريقة لتمرير البيانات من تلك الفئة إلى فئة My 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 فقط للإشارة إلى أنه يحتاج إلى التخلص الصريح، ولكن هذا يبدو مخترقًا إلى حد ما، وبينما يعمل في هذه الحالة، فمن الواضح أنه لن ينجح إذا أردت التعامل مع فئة مختومة.

هل هناك طريقة أفضل للقيام بذلك؟

هل كانت مفيدة؟

المحلول 2

في النهاية، أستخدم ببساطة المعلمات التي تقبل النوع الذي يلتف 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;
    }
}

واطلب من المعلمة أن تأخذ ذلك بدلاً من ذلك.في سمة التحويل، قم ببساطة بتعيين NeedsDisposed بناءً على ما إذا كانت المعلمة قد أخذت a MyDisposeable أو شيدت واحدة.على سبيل المثال:

if(input is MyDisposeable)
{
    return new MyDisposeableWrapper((MyDisposeable) input, false);
}
else
{
    /* construct MyDisposeable from the input */
    return new MyDisposeableWrapper(myDisposeable, true);
}

نصائح أخرى

بدلاً من التصنيف الفرعي، هل يمكنك إضافة خاصية إلى فئة 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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top