Wednesday, January 14, 2009

Nice methods in the ServiceLocator class

I just like the way these methods look. I'd take the ServiceLocator class to a job interview :)

  1. /// <summary>  
  2. /// This is used by the application when it needs an instance of T  
  3. /// </summary>  
  4. /// <param name="T">Type that the application needs an instance of</param>  
  5. /// <returns>An instance of T</returns>  
  6. public static object GetInstanceOf(Type T)  
  7. {  
  8.   lock (containerLock)  
  9.     if (container.ContainsKey(T))  
  10.       return container[T]();  
  11.   
  12.   return CreateInstance(T) ?? (OnTypeNotFound != null ? OnTypeNotFound(T) : null);  
  13. }  
  14.   
  15. /// <summary>  
  16. /// Creates a new instance of T using the "best" constructor (the one with the biggest number of arguments that are known to the service locator, with the default constructor being the last attempt)  
  17. /// </summary>  
  18. /// <param name="T">Type to instantiate</param>  
  19. /// <returns>A new instance of T or null if no suitable constructor has been found</returns>  
  20. public static object CreateInstance(this Type T)  
  21. {  
  22.   var constructor = GetBestConstructor(T);  
  23.   
  24.   return constructor != null ? constructor.Invoke() : Activator.CreateInstance(T);  
  25. }  
  26.   
  27. private static ConstructorInfo GetBestConstructor(Type T)  
  28. {  
  29.   return (from c in T.GetConstructors(BindingFlags.Public)  
  30.           let parameters = c.GetParameters()  
  31.           orderby parameters.Length descending  
  32.           where parameters.All(p => Contains(p.ParameterType))  
  33.           select c)  
  34.     .FirstOrDefault();  
  35. }  
  36.   
  37. private static object Invoke(this ConstructorInfo constructor)  
  38. {  
  39.   var arguments = constructor  
  40.     .GetParameters()  
  41.     .Select(p => GetInstanceOf(p.ParameterType))  
  42.     .ToArray();  
  43.   
  44.   return constructor.Invoke(arguments);  
  45. }  

No comments: