All Code Dies and Burns in Time

Weak Proxy Factory

In the previous article I showed how one could construct a weak proxy object using LinFu. This idea very slick, but it doesn’t do us much good unless there is something built around it.

DISCLAIMER: Blocks of this code are taken directly from the Ninject 2.0 source base and re-purposed. All code in this article is released under the same licenses as the source works (Apache 2 and MS-PL).

To start, we have IWeakCache (formerly ICache.cs) and ICachePruner.cs to describe our cache backing and the cleanup strategy. The IWeakCache is like the Ninject ICache except that I don’t provide the Get method and it takes a Weak> pointer and the source object. We can watch the weak reference for cleanup and execute it on the original object.

With this, I now have everything I need to create my WeakProxyFactory. I set up the .ctor to take an IWeakCache and ICachePruner so that we can adjust the storage and cleanup as needed. In this class, I am actually using the CommonServiceLocator to get the real object instance.

Now you can create a weak proxy simply by using the factory, or setting it up in an IoC container. To use the previous example of hooking IFoo to Foo, and injecting the weak reference into Baz objects, I can configure my application. This is going to look like a lot, but I am just being overly verbose showing how everything is set up.

So after all of this work, what does it buy me? My Baz objects now have IFoo weak proxy instances automatically injected into them when I make requests to the ServiceLocator. Once I null the pointer to the Foo object, the cache pruner will clean things up:

1234567891011121314151617181920212223242526

publicstaticclassSystemTest{privateconstintsize=6;publicstaticvoidRun(){Configure();varbazs=newList<Baz>();for(inti=0;i<size;i++){bazs.Add(ServiceLocator.Current.GetInstance<Baz>());// Where the magic happens}for(inti=0;i<size;i++){Bazbaz=bazs[i];Console.WriteLine("Foo Id: {0}",baz.Foo.Id);baz.Action();GC.Collect(2);baz.Release();GC.Collect(2);// The Foo instances are disposed of by the system for you.Thread.Sleep(100);}}}

So, we have now seen a full implementation of a weak proxy factory handing out weak substitutes for the real objects. But what can we do from here? Is there anything else? YES! Now what we have full control over the real object lifetime, we can implement pooling. So, instead of handing out pointers to new weak objects, I can reuse objects in my pool, or use a lock to wait until a resource is available. These are both potentially big projects, so I am going to keep it small for now and just show a very minimalist example.

He is a small example that will let you set the size of the pool and it will reuse instances. Every time an instance is requested, we will clean the dead objects from the pool and refill if needed.

I think that this can potentially be very useful in dealing with items such as WCF proxies. You could keep a pool and trim proxies as they age, and return them to requesters if there is no live usage, but the connection is still good.