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

http://github.com/philiplaureano/LinFu · C# · 86 lines · 41 code · 13 blank · 32 comment · 1 complexity · 2f50fb8414b26a6855fd641ecb38da8c 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. /// Defines the basic behavior of the <see cref="IMemberInjectionFilter{TMember}" /> interface.
  11. /// </summary>
  12. /// <typeparam name="TMember">The member type that will be filtered.</typeparam>
  13. public abstract class BaseMemberInjectionFilter<TMember> : IMemberInjectionFilter<TMember>, IInitialize
  14. where TMember : MemberInfo
  15. {
  16. private static readonly Dictionary<Type, IEnumerable<TMember>> _itemCache =
  17. new Dictionary<Type, IEnumerable<TMember>>();
  18. private IServiceContainer _container;
  19. /// <summary>
  20. /// Initializes the <see cref="BaseMemberInjectionFilter{TMember}" /> class.
  21. /// </summary>
  22. /// <param name="source">The host container.</param>
  23. public virtual void Initialize(IServiceContainer source)
  24. {
  25. _container = source;
  26. }
  27. /// <summary>
  28. /// Returns the list of <typeparamref name="TMember" /> objects
  29. /// whose setters will injected with arbitrary values.
  30. /// </summary>
  31. /// <remarks>This implementation selects properties that are marked with the <see cref="InjectAttribute" />.</remarks>
  32. /// <param name="targetType">The target type that contains the target properties.</param>
  33. /// <returns>A set of properties that describe which parameters should be injected.</returns>
  34. public virtual IEnumerable<TMember> GetInjectableMembers(Type targetType)
  35. {
  36. IEnumerable<TMember> items = null;
  37. // Retrieve the property list only once
  38. if (!_itemCache.ContainsKey(targetType))
  39. {
  40. // The property must have a getter and the current type
  41. // must exist as either a service list or exist as an
  42. // existing service inside the current container
  43. var members = from item in GetMembers(targetType, _container)
  44. select item;
  45. lock (_itemCache)
  46. {
  47. _itemCache[targetType] = members;
  48. }
  49. }
  50. items = _itemCache[targetType];
  51. return Filter(_container, items);
  52. }
  53. /// <summary>
  54. /// Determines which members should be selected from the <paramref name="targetType" />
  55. /// using the <paramref name="container" />
  56. /// </summary>
  57. /// <param name="targetType">The target type that will supply the list of members that will be filtered.</param>
  58. /// <param name="container">The target container.</param>
  59. /// <returns>A list of <typeparamref name="TMember" /> objects that pass the filter description.</returns>
  60. protected abstract IEnumerable<TMember> GetMembers(Type targetType, IServiceContainer container);
  61. /// <summary>
  62. /// Determines which items should be injected from the <see cref="IServiceContainer" /> instance.
  63. /// </summary>
  64. /// <param name="container">The source container that will supply the values for the selected members.</param>
  65. /// <param name="items">The list of properties that will be filtered.</param>
  66. /// <returns>A list of properties that will be injected.</returns>
  67. protected virtual IEnumerable<TMember> Filter(IServiceContainer container,
  68. IEnumerable<TMember> items)
  69. {
  70. return items;
  71. }
  72. }
  73. }