PageRenderTime 23ms CodeModel.GetById 17ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

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