DCSIMG
Disposable Property - שלמה גולדברג (הרב דוטנט)
Sign in | Join | Help

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

Disposable Property

פורסם בתאריך Feb 09 2010, 09:16 AM על ידי Shlomo | ישנם 3 תגובות

 

עדי הראה לי רעיון מאוד מעניין למימוש שמירת אובייקט זמני בזיכרון. למה הכוונה ?
 
נניח שיש לנו קוד כזה
 

public class FileLogger : ILogger

{

}

public class MockLogger : ILogger

{

}

 

public class Person

{

    public ILogger Logger { get; set; }

}

 
ויש לנו את פונקצייה שמקבלת כפרמטר Person אבל בחלק מהקוד של הפונקצייה לא רוצים שה - Logger יהיה FileLogger אלא MokeLogger - מן הסתם נעשה קוד כזה
 

public void Func(Person person)

{

    ILogger original = person.Logger;

    person.Logger = new MockLogger();

 

    //work.....

 

    person.Logger = original;

 

}

 
מה שעדי הציע - זה לעשות את הקוד הבא
 

using (DisposableProperty<ILogger>.Set(person, new MockLogger()))

{

    // work..

 

 

}

 
וכעת באורח פלא בתוך בלוג ה - using ה - Logger יהיה Mock וכשנצא מהבלוק זה יחזור להיות ה - Logger המקורי.
 
הרעיון הזה הוא נהדר בסביבות Test - תחשבו על מקרים שאתם לא באמת מעוניינים לגשת לבסיס הנתונים למשל וכו', נכון שתמיד אפשר לכתוב כמו בדוגמא הראשונה אבל הקוד הרבה יותר אלגנטי בצורה הזאת.
 
אז איך זה עובד ?
 

public class DisposableProperty<T> : IDisposable where T : class

{

    private T _original;

    private PropertyInfo _property;

    private object _obj;

 

    private DisposableProperty(object obj, T replaceValue)

    {

        if (obj == null)

            throw new ArgumentNullException();

 

        this._obj = obj;

 

        _property = obj.GetType().GetProperties().

                             FirstOrDefault(p => p.PropertyType == typeof(T));

 

        if (_property == null)

            throw new ArgumentException();

 

        _original = _property.GetValue(obj, null) as T;

 

        _property.SetValue(obj, replaceValue, null);

    }

 

    public void Dispose()

    {

        _property.SetValue(_obj, _original, null);

    }

 

    public static IDisposable Set(object obj, T replaceValue)

    {

        return new DisposableProperty<T>(obj, replaceValue);

    }

}

 
אמנם לא הכי יעיל מבחינת ביצועים - אבל בדרך כלל קוד כזה ירוץ בסביבות Tests אז לא כל כך נורא.
המתודה Set מחזירה מופע חדש של המחלקה, בבנאי שומרים את המקורי וב - Dispose מחזירים את המקורי.

רשימת תגובות

# re: Disposable Property

פורסם בתאריך Wednesday, February 10, 2010 2:43 PM על ידי Noam  

הכל טוב ויפה אבל יש לך באג די בעייתי במימוש.

אם יש לאובייקט עליו הפעלת את הDisposableProperty יותר מProperty אחד שמקבל את אותו טיפוס של T אתה בבעיה. אין לך כך כל דרך להבחין בניהם

# re: Disposable Property

פורסם בתאריך Wednesday, February 10, 2010 8:52 PM על ידי Shlomo  

נכון, זה אב טיפוס של הרעיון וצריך לשכלל אותו

# re: Disposable Property

פורסם בתאריך Tuesday, March 16, 2010 10:05 AM על ידי מרט  

לא הבנתי את זה :)

אך נראה לי אחלה רעיון....

שלח תגובה

(שדה חובה) 
(שדה חובה) 
(אופציונלי)
(שדה חובה) 

Enter the numbers above: