ServiceActivator.cs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. namespace Wayne.Lib
  5. {
  6. public static class ServiceActivator
  7. {
  8. public static T Create<T>(IServiceLocator serviceLocator, params object[] additionalParameter) where T : class
  9. {
  10. return (T)CreateInstance(string.Empty, typeof(T), serviceLocator, additionalParameter);
  11. }
  12. public static T Create<T>(string serviceId, IServiceLocator serviceLocator, params object[] additionalParameter) where T : class
  13. {
  14. return (T)CreateInstance(serviceId, typeof(T), serviceLocator, additionalParameter);
  15. }
  16. private static object CreateInstance(string servicId, Type typeToInstantiate, IServiceLocator serviceLocator, params object[] additionalParameter)
  17. {
  18. List<string> explaination = new List<string>();
  19. object result = TryCreate(typeToInstantiate, serviceLocator, servicId, explaination, additionalParameter);
  20. if (result == null)
  21. throw new ServiceContainerException(typeToInstantiate, string.Format("Could not create object of type {0} \r\n {1}", typeToInstantiate, string.Join("\r\n", explaination.ToArray())));
  22. return result;
  23. }
  24. private static object TryCreate(Type typeToCreate, IServiceLocator serviceLocator, string serviceId, List<string> explaination, params object[] additionalObjects)
  25. {
  26. var constructors = typeToCreate.GetConstructors();
  27. Array.Reverse(constructors);
  28. var parameters = new List<object>();
  29. ConstructorInfo foundConstructor = null;
  30. foreach (ConstructorInfo constructor in constructors)
  31. {
  32. var parameterInfos = constructor.GetParameters();
  33. parameters.Clear();
  34. foreach (var parameterInfo in parameterInfos)
  35. {
  36. //Check for additionalObjectMatch first!
  37. int firstMatchingParameterObjectIndex = -1;
  38. for (int index = 0; index < additionalObjects.Length; index++)
  39. {
  40. object additionalObject = additionalObjects[index];
  41. if (parameterInfo.ParameterType.IsInstanceOfType(additionalObject))
  42. {
  43. firstMatchingParameterObjectIndex = index;
  44. break;
  45. }
  46. }
  47. if (firstMatchingParameterObjectIndex >= 0)
  48. {
  49. parameters.Add(additionalObjects[firstMatchingParameterObjectIndex]);
  50. }
  51. else
  52. {
  53. var dependency = serviceLocator.TryGetService(parameterInfo.ParameterType, serviceId);
  54. if (dependency != null)
  55. {
  56. parameters.Add(dependency);
  57. }
  58. else
  59. {
  60. explaination.Add(string.Format("Could not resolve parameter {0} of type {1}", parameterInfo.Name, parameterInfo.ParameterType));
  61. }
  62. }
  63. }
  64. if (parameters.Count == parameterInfos.Length)
  65. {
  66. foundConstructor = constructor;
  67. break;
  68. }
  69. }
  70. if (foundConstructor != null)
  71. {
  72. var stateObject = foundConstructor.Invoke(parameters.ToArray());
  73. return stateObject;
  74. }
  75. return null;
  76. }
  77. }
  78. }