/src/COFE3/app/COFE3.Core/Implements/PropertyBehaviorManager.cs

http://cofe.codeplex.com · C# · 235 lines · 178 code · 57 blank · 0 comment · 52 complexity · a9a1af58647a97cbb54bf4be8c45abc3 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.Composition;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Cofe.Core.Service;
  8. using Cofe.Core.Utils;
  9. namespace Cofe.Core.Property
  10. {
  11. public class PropertyBehaviorManager : IPropertyBehaviorManager
  12. {
  13. [Export(typeof(ICofeService))]
  14. [ServicePriority(ServicePriorityAttribute.DefaultPriority_COFE)]
  15. public class Factory : IPropertyBehaviorManagerFactory
  16. {
  17. public IPropertyBehaviorManager ConstructBehavior(IPropertyHost propertyHost, IServiceLocater serviceLocater)
  18. {
  19. return new PropertyBehaviorManager(propertyHost, serviceLocater);
  20. }
  21. }
  22. #region Constructor
  23. private void init(IServiceLocater serviceLocater)
  24. {
  25. _propertyDictionary = serviceLocater.FindService<IPropertyDictionary>();
  26. }
  27. private PropertyBehaviorManager(IPropertyHost propertyHost, IServiceLocater serviceLocater)
  28. {
  29. _propertyHost = propertyHost;
  30. init(serviceLocater);
  31. }
  32. #endregion
  33. #region Methods
  34. private static Dictionary<PropertyRetrivalOptions, T> loadBehaviors<T>()
  35. where T : IPropertyProviderBehavior
  36. {
  37. var retVal = new Dictionary<PropertyRetrivalOptions, T>();
  38. var allListBehavior = CofeServices.ServiceLocater.FindAllServices<T>();
  39. foreach (var name in Enum.GetNames(typeof(PropertyRetrivalOptions)))
  40. {
  41. PropertyRetrivalOptions option;
  42. Enum.TryParse<PropertyRetrivalOptions>(name, out option);
  43. var behavior = allListBehavior.FirstOrDefault(b => b.SupportOption.HasFlag(option));
  44. retVal.Add(option, behavior);
  45. }
  46. return retVal;
  47. }
  48. private static void loadBehaviors()
  49. {
  50. if (_listBehavior == null) _listBehavior = loadBehaviors<IPropertyListSupportedBehavior>();
  51. if (_getBehavior == null) _getBehavior = loadBehaviors<IPropertyGetBehavior>();
  52. if (_setBehavior == null) _setBehavior = loadBehaviors<IPropertySetBehavior>();
  53. }
  54. public async Task<object[]> GetSupportedPropertyAsync(PropertyRetrivalOptions options = PropertyRetrivalOptions.NotApplied,
  55. MatchMode matchMode = MatchMode.All, params IPropertyFilter[] filters)
  56. {
  57. object[] supportedProperty;
  58. if (_propertyHost.PropertyCache != null && _propertyHost.PropertyCache.SupportedDefinitions.IsPropertySupported(CacheProperties.SupportedProperties))
  59. supportedProperty = (await _propertyHost.PropertyCache.GetOnePropertyAsync(CacheProperties.SupportedProperties))
  60. .ValueAs<object[]>();
  61. else
  62. {
  63. await _propertyHost.ConnectAsync();
  64. loadBehaviors();
  65. var behavior = _listBehavior[options];
  66. if (behavior == null) throw new NotSupportedException("Behavior");
  67. supportedProperty = behavior.GetSupportedProperty(_propertyHost.AllPropertyProviders).ToArray();
  68. }
  69. return PropertyUtils.FilterProperty(supportedProperty.ToList(), matchMode, filters).ToArray();
  70. }
  71. public bool IsPropertySupported(object property)
  72. {
  73. return GetSupportedPropertyAsync().Result.Contains(property);
  74. }
  75. public async Task<PropertyPair> GetPropertyAsync(object property)
  76. {
  77. if (property is string)
  78. {
  79. object propertyObject = _propertyHost.ServiceLocater.FindService<IPropertyDictionary>().GetProperty((string)property);
  80. return await GetPropertyAsync(propertyObject);
  81. }
  82. var options = PropertyUtils.GetPropertyRetrivalOptions(property);
  83. loadBehaviors();
  84. var behavior = _getBehavior[options];
  85. if (behavior == null) throw new NotSupportedException("Behavior");
  86. var retVal = await behavior.GetPropertyAsync(property, _propertyHost.AllPropertyProviders, options);
  87. if (retVal == null && _propertyHost.PrimaryPropertyProvider == null)
  88. {
  89. await _propertyHost.ConnectAsync();
  90. retVal = await behavior.GetPropertyAsync(property, _propertyHost.AllPropertyProviders, options);
  91. }
  92. if (retVal != null)
  93. return retVal;
  94. throw new NotSupportedException(property.ToString());
  95. }
  96. public async Task<bool> SetPropertyAsync(PropertyPair propertyPair)
  97. {
  98. var options = PropertyUtils.GetPropertyRetrivalOptions(propertyPair.Property);
  99. loadBehaviors();
  100. var behavior = _setBehavior[options];
  101. if (behavior == null) throw new NotSupportedException("Behavior");
  102. if (options != PropertyRetrivalOptions.First) //If First, then PropertyCache will be updated only.
  103. await _propertyHost.ConnectAsync(); //Have to write to main.
  104. return await behavior.SetPropertyAsync(_propertyHost.AllPropertyProviders, propertyPair, options);
  105. }
  106. public async Task<T> InvokeAsync<T>(object property, ParameterDic parameters = null)
  107. {
  108. if (parameters == null) parameters = new ParameterDic();
  109. if (!IsPropertySupported(property))
  110. {
  111. var relatedProperty = PropertyUtils.FindRelatedProperty(property);
  112. if (relatedProperty != null && IsPropertySupported(relatedProperty))
  113. return Invoke<T>(relatedProperty, parameters);
  114. else throw new NotSupportedException();
  115. }
  116. PropertyPair ppair = await GetPropertyAsync(property);
  117. return await _propertyDictionary.PropertyInvoker.InvokeAsync<T>(ppair, parameters);
  118. }
  119. public async Task InvokeAsync(object property, ParameterDic parameters = null)
  120. {
  121. if (parameters == null) parameters = new ParameterDic();
  122. if (!IsPropertySupported(property))
  123. {
  124. var relatedProperty = PropertyUtils.FindRelatedProperty(property);
  125. if (relatedProperty != null && IsPropertySupported(relatedProperty))
  126. {
  127. Invoke(relatedProperty, parameters);
  128. return;
  129. }
  130. else throw new NotSupportedException();
  131. }
  132. PropertyPair ppair = await GetPropertyAsync(property);
  133. await _propertyDictionary.PropertyInvoker.InvokeAsync(ppair, parameters);
  134. }
  135. public T Invoke<T>(object property, ParameterDic parameters = null)
  136. {
  137. if (parameters == null) parameters = new ParameterDic();
  138. if (!IsPropertySupported(property))
  139. {
  140. var relatedProperty = PropertyUtils.FindRelatedProperty(property);
  141. if (relatedProperty != null && IsPropertySupported(relatedProperty))
  142. {
  143. return Task.Run<T>(async () => await InvokeAsync<T>(relatedProperty, parameters)).Result;
  144. }
  145. else throw new NotSupportedException();
  146. }
  147. PropertyPair ppair = this.GetProperty(property);
  148. return _propertyDictionary.PropertyInvoker.Invoke<T>(ppair, parameters);
  149. }
  150. public void Invoke(object property, ParameterDic parameters = null)
  151. {
  152. if (parameters == null) parameters = new ParameterDic();
  153. if (!IsPropertySupported(property))
  154. {
  155. var relatedProperty = PropertyUtils.FindRelatedProperty(property);
  156. if (relatedProperty != null && IsPropertySupported(relatedProperty))
  157. {
  158. InvokeAsync(relatedProperty, parameters).RunSynchronously();
  159. return;
  160. }
  161. else throw new NotSupportedException();
  162. }
  163. PropertyPair ppair = this.GetProperty(property);
  164. _propertyDictionary.PropertyInvoker.Invoke(ppair, parameters);
  165. }
  166. #endregion
  167. #region Data
  168. private IPropertyDictionary _propertyDictionary;
  169. private IPropertyHost _propertyHost;
  170. static Dictionary<PropertyRetrivalOptions, IPropertyListSupportedBehavior> _listBehavior;
  171. static Dictionary<PropertyRetrivalOptions, IPropertyGetBehavior> _getBehavior;
  172. static Dictionary<PropertyRetrivalOptions, IPropertySetBehavior> _setBehavior;
  173. #endregion
  174. #region Public Properties
  175. public IPropertyHost PropertyHost { get { return _propertyHost; } }
  176. #endregion
  177. }
  178. }