w.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. namespace OpenSEMI.Core.Container
  6. {
  7. public class w : IContainer, IServiceProvider
  8. {
  9. private readonly ConcurrentDictionary<Type, CachedTypeInfo> _serviceTypeLookup = new ConcurrentDictionary<Type, CachedTypeInfo>();
  10. private readonly ConcurrentDictionary<Type, object> _serviceInstanceLookup = new ConcurrentDictionary<Type, object>();
  11. private readonly ConcurrentDictionary<Type, Action<object>> _serviceTypeCallbackLookup = new ConcurrentDictionary<Type, Action<object>>();
  12. public void Register<TService, TImplementation>() where TImplementation : TService
  13. {
  14. _serviceTypeLookup[typeof(TService)] = new CachedTypeInfo
  15. {
  16. Type = typeof(TImplementation),
  17. IsSingleton = true
  18. };
  19. }
  20. public void Register<TService, TImplementation>(bool singleton = true) where TImplementation : TService
  21. {
  22. _serviceTypeLookup[typeof(TService)] = new CachedTypeInfo
  23. {
  24. Type = typeof(TImplementation),
  25. IsSingleton = singleton
  26. };
  27. }
  28. public void Register<TService>(Type implementationType, bool singleton = true)
  29. {
  30. if (implementationType == (Type)null)
  31. {
  32. throw new ArgumentNullException("implementationType cannot be null.");
  33. }
  34. _serviceTypeLookup[typeof(TService)] = new CachedTypeInfo
  35. {
  36. Type = implementationType,
  37. IsSingleton = singleton
  38. };
  39. }
  40. public void Register<TService>(Type implementationType, Action<TService> callback, bool singleton = true)
  41. {
  42. if (implementationType == (Type)null)
  43. {
  44. throw new ArgumentNullException("serviceType cannot be null.");
  45. }
  46. _serviceTypeLookup[typeof(TService)] = new CachedTypeInfo
  47. {
  48. Type = implementationType,
  49. IsSingleton = singleton
  50. };
  51. if (callback != null)
  52. {
  53. _serviceTypeCallbackLookup[typeof(TService)] = delegate(object x)
  54. {
  55. callback((TService)x);
  56. };
  57. }
  58. }
  59. public void Register(Type serviceType, Type implementationType, bool singleton = true)
  60. {
  61. if (serviceType == (Type)null)
  62. {
  63. throw new ArgumentNullException("serviceType cannot be null.");
  64. }
  65. if (implementationType == (Type)null)
  66. {
  67. throw new ArgumentNullException("serviceType cannot be null.");
  68. }
  69. if (!serviceType.IsAssignableFrom(implementationType))
  70. {
  71. throw new ArgumentException($"Service could not be registered. {implementationType.Name} does not implement {serviceType.Name}.");
  72. }
  73. _serviceTypeLookup[serviceType] = new CachedTypeInfo
  74. {
  75. Type = implementationType,
  76. IsSingleton = singleton
  77. };
  78. }
  79. public void Register<TService>(TService instance)
  80. {
  81. if (instance == null)
  82. {
  83. throw new ArgumentNullException("instance cannot be null.");
  84. }
  85. _serviceInstanceLookup[typeof(TService)] = instance;
  86. }
  87. public T Resolve<T>()
  88. {
  89. return (T)Resolve(typeof(T));
  90. }
  91. private object Resolve(Type type)
  92. {
  93. object value = null;
  94. if (!_serviceTypeLookup.TryGetValue(type, out CachedTypeInfo value2))
  95. {
  96. Register(type, type, true);
  97. CachedTypeInfo cachedTypeInfo = default(CachedTypeInfo);
  98. cachedTypeInfo.Type = type;
  99. cachedTypeInfo.IsSingleton = true;
  100. value2 = cachedTypeInfo;
  101. }
  102. if (_serviceInstanceLookup.TryGetValue(type, out value))
  103. {
  104. return value;
  105. }
  106. ConstructorInfo constructor = ConstructorCache.GetConstructor(value2.Type);
  107. if (constructor != (ConstructorInfo)null)
  108. {
  109. List<ParameterInfo> parameters = ParameterCache.GetParameters(constructor);
  110. List<object> list = new List<object>();
  111. foreach (ParameterInfo item in parameters)
  112. {
  113. list.Add(Resolve(item.ParameterType));
  114. }
  115. object obj = Activator.CreateInstance(value2.Type, list.ToArray());
  116. if (_serviceTypeCallbackLookup.TryGetValue(type, out Action<object> value3))
  117. {
  118. value3(obj);
  119. }
  120. if (value2.IsSingleton)
  121. {
  122. _serviceInstanceLookup[type] = obj;
  123. }
  124. return obj;
  125. }
  126. return null;
  127. }
  128. public bool IsRegistered<TService>()
  129. {
  130. if (_serviceTypeLookup.ContainsKey(typeof(TService)) || _serviceInstanceLookup.ContainsKey(typeof(TService)))
  131. {
  132. return true;
  133. }
  134. return false;
  135. }
  136. public object GetService(Type serviceType)
  137. {
  138. return Resolve(serviceType);
  139. }
  140. }
  141. }