A JustInTime class

I discovered in my code a redundant pattern :

private SomeType _something;
private SomeType something { get { if (_something == null) _something = new SomeType(....); return _something;} }

Usefull in Silverlight, when your Blender always say “Can’t compile ! Strange errors ! but compiles when i comment your WebClient… in ctor of that class…”
So i use it to have members builded the first time they are used, “Just in time”.
/!\ It’s not a Singleton ! i can have others instance of this class new-ing it directly !
/!\ Singleton is Evil // feed the Troll

So i factorized it :

 
public class Jit<T>
{
  T _instance;
  object[] _ctor_params;
 
  public Jit(object[] ctor_params)
    {
      _ctor_params = ctor_params;
    }
 
  public Jit()
    {
    }
 
  public T create(object[] ctor_params)
    {
      Type[] param_types = ctor_params.Aggregate<object, List<Type>>(
			     new List<Type>(),
			     (List<Type> lt, object o) =>
	                       {
				 lt.Add(o.GetType());
				 return lt;
			       }).ToArray();
      var ctor = typeof(T).GetConstructor(param_types);
      if (ctor == null)
	throw new Exception(param_types.Aggregate<Type, String>(
		      "No constructor found for " + typeof(T).Name + " taking",
         	      (string i, Type t) => { return i + " " + t.Name; }));
      return (T)ctor.Invoke(_ctor_params);
    }
 
  public T create()
    {
      return (_ctor_params == null)
	? create(new object[] { })
	: create(_ctor_params);
    }
 
  public T single()
    {
      if (_instance == null)
	_instance = create();
      return _instance;
    }
}

A usage demo :

 
public class Test
{
  Test(string foo, int bar)
    {
      Console.WriteLine("Test ctor with : " + foo + " and " + bar);
    }
 
  public void foo()
    {
      Console.WriteLine("bar");
    }
}
 
public partial class Page : UserControl
{
  public event EventHandler my_event;
  private Jit<Test> test = new Jit<Test>(new object[]{"42", 42});
 
  public Page()
    {
      InitializeComponent();
      // test is not yet built
      test.single().foo(); // Whill build a Test and call foo()
      test.single().foo(); // Whill call foo on the same Test.
    }
}

So a :

private SomeType _something;
private SomeType something { get { if (_something == null) _something = new SomeType(....); return _something;} }

became :

private Jit<SomeType> something = new Jit<SomeType>(new object[]{...});

Note the Jit ctor, taking a array of objects, it’s the objects to pass to your ctor’s class (found by reflection using their types)

This entry was posted in Code. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>