/src/LinFu.IoC/Configuration/Injectors/AttributedPropertyInjectionFilter.cs

http://github.com/philiplaureano/LinFu · C# · 91 lines · 52 code · 9 blank · 30 comment · 8 complexity · fa020832a002f88826408fff84339150 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using LinFu.IoC.Configuration.Interfaces;
  6. using LinFu.IoC.Interfaces;
  7. namespace LinFu.IoC.Configuration
  8. {
  9. /// <summary>
  10. /// A default implementation of the <see cref="IMemberInjectionFilter{TMember}" />
  11. /// class that returns properties which have the <see cref="InjectAttribute" />
  12. /// defined.
  13. /// </summary>
  14. [Implements(typeof(IMemberInjectionFilter<PropertyInfo>), LifecycleType.OncePerRequest)]
  15. public class AttributedPropertyInjectionFilter : BaseMemberInjectionFilter<PropertyInfo>
  16. {
  17. private readonly Type _attributeType;
  18. /// <summary>
  19. /// Initializes the class and uses the <see cref="InjectAttribute" />
  20. /// to specify which properties should be automatically injected with
  21. /// services from the container.
  22. /// </summary>
  23. public AttributedPropertyInjectionFilter()
  24. {
  25. _attributeType = typeof(InjectAttribute);
  26. }
  27. /// <summary>
  28. /// Initializes the class and uses the <paramref name="attributeType" />
  29. /// to specify which properties should be automatically injected with
  30. /// services from the container.
  31. /// </summary>
  32. /// <param name="attributeType">The custom property attribute that will be used to mark properties for automatic injection.</param>
  33. public AttributedPropertyInjectionFilter(Type attributeType)
  34. {
  35. _attributeType = attributeType;
  36. }
  37. /// <summary>
  38. /// Determines which properties should be injected from the <see cref="IServiceContainer" /> instance.
  39. /// </summary>
  40. /// <param name="container">The source container that will supply the property values for the selected properties.</param>
  41. /// <param name="properties">The list of properties to be filtered.</param>
  42. /// <returns>A list of properties that should be injected.</returns>
  43. protected override IEnumerable<PropertyInfo> Filter(IServiceContainer container,
  44. IEnumerable<PropertyInfo> properties)
  45. {
  46. // The property must have the custom attribute defined
  47. var results = from p in properties
  48. let propertyType = p.PropertyType
  49. let attributes = p.GetCustomAttributes(_attributeType, false)
  50. where attributes != null && attributes.Length > 0
  51. select p;
  52. return results;
  53. }
  54. /// <summary>
  55. /// Determines which members should be selected from the <paramref name="targetType" />
  56. /// using the <paramref name="container" />
  57. /// </summary>
  58. /// <param name="targetType">The target type that will supply the list of members that will be filtered.</param>
  59. /// <param name="container">The target container.</param>
  60. /// <returns>A list of <see cref="PropertyInfo" /> objects that pass the filter description.</returns>
  61. protected override IEnumerable<PropertyInfo> GetMembers(Type targetType, IServiceContainer container)
  62. {
  63. IEnumerable<PropertyInfo> results;
  64. try
  65. {
  66. var items =
  67. from p in targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
  68. let propertyType = p == null ? typeof(void) : p.PropertyType
  69. let isServiceArray = propertyType != null ? propertyType.ExistsAsServiceArray() : ioc => false
  70. let isCompatible = isServiceArray(container) || container.Contains(propertyType)
  71. where p != null && p.CanWrite && isCompatible
  72. select p;
  73. results = items;
  74. }
  75. catch (Exception ex)
  76. {
  77. throw ex;
  78. }
  79. return results;
  80. }
  81. }
  82. }