سؤال

ولدي المفرد يستخدم "للقراءة فقط ثابتة T = مثيل جديد T ()؛" نمط. ومع ذلك، وأنا واجهت حالة حيث T هو المتاح، وفعلا يحتاج إلى أن يتم التخلص من أجل وحدة الاختبارات. كيف يمكنني تعديل هذا النمط لدعم المفرد القابل للتصرف؟

واجهة أود شيء مثل:

var x = Foo.Instance;
var y = Foo.Instance; // x == y
...
x.Release(); // this causes the next Foo.Instance to return a fresh object
             // also, it assumes no further operations on x/y will be performed.

ملحوظة - نمط يجب أن يكون الخيط آمنة، وبالطبع

.

تعديل - يمكنك لغرض رمز الإنتاج، وهذا هو المفرد صحيح. الشيء هو أن تستقر بعض الملفات، وذلك لتنظيف في وحدة الاختبارات لدينا للتخلص منه.

وأود أيضا أن تفضل النمط الذي يمكن إعادة استخدامها، إذا أمكن ذلك.

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

المحلول

وRelease إجعلها internal واستخدام السمة InternalsVisibleTo لفضح فقط على وحدتك اختبار التجمع. يمكنك إما أن تفعل ذلك، أو إذا كنت شخص ما سوف نكون حذرين في التجمع الخاص الذي يطلق عليه، يمكنك وضع علامة على أنها private والوصول إليه باستخدام الانعكاس.

استخدم في finalizer في المفرد الخاص الذي يستدعي الأسلوب Dispose على سبيل المثال المفرد.

في رمز الإنتاج، لن يؤدي إلا إلى التفريغ من AppDomain يسبب التخلص من المفرد. في رمز الاختبار، يمكنك الشروع في الدعوة إلى Release نفسك.

نصائح أخرى

وعند هذه النقطة وأنا لا أعتقد أن النظر حقا أن يكون المفرد أكثر من ذلك، أن نكون صادقين.

وعلى وجه الخصوص، إذا عميل يستخدم المفرد انهم حقا لن نتوقع أن لديهم للتخلص منها، وأنها سأشعر بالدهشة إذا لم شخص آخر.

ما هو رمز الإنتاج الخاص بك سوف تفعل؟

وتحرير: إذا كنت حقا، حقا بحاجة هذا للاختبارات وحدة و<م> فقط للاختبارات وحدة (الذي يبدو موضع شك من حيث التصميم، لأكون صريحا) ثم هل يمكن أن عزف دائما مع انعكاس الحقل باستخدام . وسيكون من أجمل للعمل على ما إذا كان ينبغي <م> حقا أن يكون المفرد أو ما إذا كان ينبغي <م> حقا يكون التخلص منها على الرغم من - وهما نادرا ما يسيران جنبا إلى جنب

يجب

وسنغلتونس لا يمكن التخلص منها. فترة. إذا شخص ما يدعو تخلص قبل الأوان، هو مشدود طلبك حتى إعادة تشغيله.

 public class Foo : IDisposable
  { [ThreadStatic] static Foo _instance = null;

    private Foo() {IsReleased = false;}

    public static Foo Instance
     { get
        { if (_instance == null) _instance = new Foo();
          return _instance;
        }
     }

    public void Release()
     { IsReleased = true;
       Foo._instance = null;
     }

    void IDisposable.Dispose() { Release(); }

    public bool IsReleased { get; private set;}

  }

إذا الطبقة تنفذ IDisposable (كما يعني أنه لا) ثم مجرد دعوة x.Dispose ()

هل يمكن استخدام المفرد كسول متداخلة (انظر هنا ) مع بعض تعديلات بسيطة:

public sealed class Singleton : IDisposable
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (!Nested.released)
                return Nested.instance;
            else
                throw new ObjectDisposedException();
        }
    }

    public void Dispose()
    {
         disposed = true;
         // Do release stuff here
    }

    private bool disposed = false;

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

وتذكر أن رمي ObjectDisposedException في جميع طرق / الممتلكات العامة من وجوه إذا تم التخلص منها.

ويجب عليك أيضا، توفير طريقة finalizer لكائن، في حالة تخلص لا الحصول على استدعاء. معرفة كيفية تنفيذ IDisposable هنا بشكل صحيح.

لوحدة الاختبارات هل يمكن استخدام "اليدوي" مثلا (ولكن كنت بحاجة إلى وسيلة لإنشاء الكائن).

في قضيتك، وربما يجب عليك استخدام أفضل نمط مصنع (مجردة / طريقة - أيهما أفضل لقضيتك)، جنبا إلى جنب مع المفرد

إذا كنت ترغب في معرفة ما إذا تم التخلص من المفرد صحيح من الأشياء المستخدمة (في اختبار وحدة)، ثم استخدام الأسلوب مصنع، وإلا استخدام نمط المفرد.

وبالمناسبة، إذا لم يكن لديك الوصول إلى شفرة المصدر المفرد أو لا يسمح لك لتعديله، وكنت التفاف أفضل لالمفرد آخر، وتقديم كل منطق من واحدة جديدة (أشبه الوكيل). هذا يبدو وكأنه مبالغة، ولكنه يمكن أن يكون حلا قابلا للتطبيق.

وأيضا، من أجل أن تكون قادرة على السيطرة على الوصول إليها، وتوفير المصنع، والسماح للعملاء الحصول على كائن جديد فقط إذا لم يتم التخلص من الكائن.

وثمة خيار آخر لجعل سينغلتون المتاح هو استخدام القلعة الرملية في [سينغلتون] atribute للفئة الخاصة بك، ثم يأخذ الإطار قلعة الرعاية للتخلص كل كائنات فريد المتاح

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top