views:

72

answers:

4

I need a way to track instances of various classes, without those classes having any knowledge that they are being tracked. Essentially, I have a class factory which creates instances and hands them off to another thread. Once that thread completes and unloads the instance, I need to get notified of that so I can do reference counting and exit from my class factory when all the instances are gone.

The challenge is that I can't modify any of the classes I'll bve loading, because I don't control their source code.

Tracking the instances I create is simple, I can just put them in some sort of collection as I create them. Tracking their destruction is causing me problems. If I could modify the source code, I'd add an event to each class and when I create an instance, I'd hook into the event and use that as my notification. But I can't do that.

So, the question is this: is there a sneaky way to monitor an object instance and detect when it is being destroyed?

A: 

How about you control the destruction of the object:

public void Destroy(T obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");
    if (!_living.Contains(obj))
        throw new ArgumentException("Where did this obj come from?");

    using (obj as IDisposable)
    {

    }

    _living.Remove(obj); // List?
}
ChaosPandion
So what calls Destroy()? Remember I can't control the types I'm loading (in fact they are loaded dynamically from a folder and I don't know in advance what I will find there).
Tim Long
+6  A: 

Since you're creating the objects, it seems like you could return a Decorator instead of the actual instance.

By using the Decorator Pattern, you could "wrap" the returned object in your own, decorated API. The decoration could provide an IDisposable implementation that provided your destruction notification.

Reed Copsey
This is nice. You can use refection to generate the decorator to. This would be important if the class is massive.
ChaosPandion
That's very interesting, I will follow this up. Thanks.
Tim Long
+1  A: 

There isn't a way to get active notification, but you could keep a WeakReference to the objects and periodically check if any have died.

Edit: I like Reed's answer better than mine!

Stephen Cleary
+1 That's funny - I was thinking this same exact thing, until I read the part where he said he was controlling the construction of the objects ;)
Reed Copsey
This actually looks like it might be the most workable solution in my situation, I'm going to give this a try.
Tim Long
+1  A: 

If you hold a list of the references to the instances you create they will not get garbage collected and so will never be destroyed...

Instead you can create a repository that holds a list of Guids and create a new Guid for each instance and then add it to a list instead - something like a FactoryRepository. In this way you do not have a reference problem for garbage collection as Guids are structs rather than reference types. You could then inherit from each class to create a type that can notify on destroy. I am assuming that as you cannot alter the code of the original classes, you cannot also alter the consumers of these classes, therefore something like the decorator pattern (via an interface) is out because the types would not be compatible.

Very simplified example:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

    public OriginalClassDestroyNotifier(Guid instanceId)
    {
        _instanceId = instanceId;
    }

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}
chibacity