ServiceActivator.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. object result = TryCreate(typeToInstantiate, serviceLocator, servicId, additionalParameter);
  19. if (result == null)
  20. throw new ServiceContainerException(typeToInstantiate, "Could not create object");
  21. return result;
  22. }
  23. private static object TryCreate(Type typeToCreate, IServiceLocator serviceLocator, string serviceId, params object[] additionalObjects)
  24. {
  25. var constructors = typeToCreate.GetConstructors();
  26. Array.Reverse(constructors);
  27. var parameters = new List<object>();
  28. ConstructorInfo foundConstructor = null;
  29. foreach (ConstructorInfo constructor in constructors)
  30. {
  31. var parameterInfos = constructor.GetParameters();
  32. parameters.Clear();
  33. foreach (var parameterInfo in parameterInfos)
  34. {
  35. //Check for additionalObjectMatch first!
  36. int firstMatchingParameterObjectIndex = -1;
  37. for (int index = 0; index < additionalObjects.Length; index++)
  38. {
  39. object additionalObject = additionalObjects[index];
  40. if (parameterInfo.ParameterType.IsAssignableFrom(additionalObject.GetType()))
  41. {
  42. firstMatchingParameterObjectIndex = index;
  43. break;
  44. }
  45. }
  46. if (firstMatchingParameterObjectIndex >= 0)
  47. {
  48. parameters.Add(additionalObjects[firstMatchingParameterObjectIndex]);
  49. }
  50. else
  51. {
  52. var dependency = serviceLocator.TryGetService(parameterInfo.ParameterType, serviceId);
  53. if (dependency != null)
  54. {
  55. parameters.Add(dependency);
  56. }
  57. }
  58. }
  59. if (parameters.Count == parameterInfos.Length)
  60. {
  61. foundConstructor = constructor;
  62. break;
  63. }
  64. }
  65. if (foundConstructor != null)
  66. {
  67. var stateObject = foundConstructor.Invoke(parameters.ToArray());
  68. return stateObject;
  69. }
  70. return null;
  71. }
  72. }
  73. }