Reputation: 10773
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<BaseObject>
{
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.
Upvotes: 2
Views: 3288
Reputation: 55184
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.
Upvotes: 3