Follow up: A little C# inspired by Ruby - No Fluff Just Stuff

Follow up: A little C# inspired by Ruby

Posted by: Venkat Subramaniam on March 8, 2007

In response to my previous post, Duncan M. wrote earlier today...

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.
Venkat Subramaniam

About Venkat Subramaniam

Dr. Venkat Subramaniam is an award-winning author, founder of Agile Developer, Inc., creator of agilelearner.com, and an instructional professor at the University of Houston.

He has trained and mentored thousands of software developers in the US, Canada, Europe, and Asia, and is a regularly-invited speaker at several international conferences. Venkat helps his clients effectively apply and succeed with sustainable agile practices on their software projects.

Venkat is a (co)author of multiple technical books, including the 2007 Jolt Productivity award winning book Practices of an Agile Developer. You can find a list of his books at agiledeveloper.com. You can reach him by email at venkats@agiledeveloper.com or on twitter at @venkat_s.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »