Hi Venkat
your blog engine didn't like me leaving this comment (must have been the dodgy use of reflection :-))
<snip>
Just for kicks I tryed to make this pattern more generic:
namespace ResourceCleanExample
{
public delegate void AutoDisposeDelegate<T>(T resource) where T : IDisposable;
public class Using
{
public static void Use<T>(AutoDisposeDelegate<T> resourceHelper) where T : IDisposable
{
ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
T resource = (T)constructor.Invoke(null);
try
{
resourceHelper(resource);
}
finally
{
resource.Dispose();
}
}
}
}
Yes, I failed to do it without reflection :-( but now we can use the following:
Using.Use<Resource>(delegate(Resource r)
{
r.someOp1();
r.someOp2();
}
);
</snip>
And in a follow up email he writes:
which should have probably been written
public static void Use<T>(AutoDisposeDelegate<T> resourceHelper) where T : IDisposable
{
ConstructorInfo constructor = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null);
using (T resource = (T)constructor.Invoke(null))
{
resourceHelper(resource);
}
}
..........End of Duncan's message..........
Interesting though! I like the intent to Templatize it. It would be great if the reflection part can be avoided.
So, I tried creating an interface IFactory<T> with a property T Instance { get; } and the Use method can then
call the Instance property on IFactory to get the instance. I implemented a ResourceFactory as a nested class of
Resource (this nested class can use the private constructor of Resource). This make the code look like this:
public delegate void UseHelper<T>(T resource) where T : IDisposable;
public interface IFactory<T>
{
T Instance { get; }
}
public class UseResource<T> where T : IDisposable
{
public static void Use(IFactory<T> factory, UseHelper<T> helper)
{
using(T obj = factory.Instance)
{
helper(obj);
}
}
}
class Resource : IDisposable
{
private Resource()
{
Console.WriteLine("Pre-processing is taken care...");
}
#region IDisposable Members
public void Dispose()
{
Console.WriteLine("Any cleanup or post-processing is taken care...");
}
#endregion
public void someOp1() { Console.WriteLine("Some op1 done..."); }
public void someOp2() { Console.WriteLine("Some op2 done..."); }
public class ResourceFactory : IFactory<Resource>
{
public Resource Instance
{
get
{
return new Resource();
}
}
}
}
Not too elegant, but that's all my little brain can think at this hour.