PageRenderTime 233ms CodeModel.GetById 110ms app.highlight 4ms RepoModel.GetById 117ms app.codeStats 0ms

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