views:

417

answers:

1

I was exploring about Extensible object pattern using (IExtension, IExtensibleObject) interfaces in C#, I came with a very simple example to convert dates to UTC from local and vice-versa:

public class BaseObject : IExtensibleObject<BaseObject> 
    {
        private DateTime _startDate;
        private ExtensionCollection<BaseObject> _extensions;

        public DateTime StartDate
        {
            get { return _startDate; }
            set { _startDate = value; }
        }

        public BaseObject()
        {
            StartDate = DateTime.Now;
            _extensions = new ExtensionCollection<BaseObject>(this); 
        }

        #region IExtensibleObject<BaseObject> Members

        public IExtensionCollection<BaseObject> Extensions
        {
            get 
            {
                return _extensions;
            }
        }

        #endregion
    }

public class DateTimeConverterExtension : IExtension { private BaseObject _owner;

    #region IExtension<BaseObject> Members

    public void Attach(BaseObject owner)
    {
        _owner = owner;
        _owner.StartDate = owner.StartDate.ToUniversalTime();
    }

    public void Detach(BaseObject owner)
    {
        _owner.StartDate = _owner.StartDate.ToLocalTime();
    }

    #endregion
}

  class Program
    {
        static void Main(string[] args)
        {
            BaseObject obj = new BaseObject();
            Console.WriteLine("Local Time: "+obj.StartDate);

            obj.Extensions.Add(new DateTimeConverterExtension());


            Console.WriteLine("UTC: "+obj.StartDate);

            DateTimeConverterExtension ext = obj.Extensions.Find<DateTimeConverterExtension>();
            obj.Extensions.Remove(ext);

            Console.WriteLine("Local Time: "+obj.StartDate);
        }
    }

Output: Local Time: 4/13/2009 11:09:19 AM UTC: 4/13/2009 5:39:19 AM Local Time: 4/13/2009 11:09:19 AM Press any key to continue . . .

So it works, the question is: How does .Net framework invoke "Attach" and "Detach" when IExtensionCollection.Add and IExtensionCollection.Detach methods are invoked by the program? Fill in the internal details which I am missing here.

+1  A: 

The Attach and Detach methods are called by ExtensionCollection<T>.InsertItem and ExtensionsCollection<T>.RemoveItem, respectively. These methods, in turn, are virtual methods called by SynchronizedCollection<T>.Add and SynchronizedCollection<T>.Remove, which is what your code ends up calling into. This can be verified by using Reflector. If you created your own implementation of IExtensionCollection<T>, there's no guarantee that Attach and Detach would be called correctly.

kvb