1: /*
2: Copyright (c) 2011 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System;
24: using System.Collections.Generic;
25: using System.Linq;
26: using System.Text;
27: using Utilities.IoC.Mappings;
28: using Utilities.IoC.Mappings.Interfaces;
29: using System.Reflection;
30: using Utilities.IoC.Mappings.Attributes;
31: using Utilities.IoC.Providers.BaseClasses;
32: using Utilities.DataTypes.ExtensionMethods;
33: using Utilities.Reflection.ExtensionMethods;
34: #endregion
35:
36: namespace Utilities.IoC.Providers.Implementations
37: {
38: /// <summary>
39: /// Standard implementation class
40: /// </summary>
41: public class Standard : BaseImplementation
42: {
43: #region Constructor
44:
45: /// <summary>
46: /// Constructor
47: /// </summary>
48: /// <param name="ImplementationType">Implementation type</param>
49: /// <param name="MappingManager">Mapping manager</param>
50: public Standard(Type ImplementationType, MappingManager MappingManager)
51: {
52: this.ReturnType = ImplementationType;
53: this.MappingManager = MappingManager;
54: }
55:
56: #endregion
57:
58: #region Functions
59:
60: #region Create
61:
62: public override object Create()
63: {
64: ConstructorInfo Constructor = Utils.ConstructorList.ChooseConstructor(ReturnType, MappingManager);
65: object Instance = CreateInstance(Constructor);
66: SetupProperties(Instance);
67: SetupMethods(Instance);
68: return Instance;
69: }
70:
71: #endregion
72:
73: #region SetupMethods
74:
75: private void SetupMethods(object Instance)
76: {
77: if (Instance.IsNull())
78: return;
79: foreach (MethodInfo Method in Instance.GetType().GetMethods().Where(x => IsInjectable(x)))
80: Method.Invoke(Instance, Method.GetParameters().ForEach(x => CreateInstance(x)).ToArray());
81: }
82:
83: #endregion
84:
85: #region SetupProperties
86:
87: private void SetupProperties(object Instance)
88: {
89: if (Instance.IsNull())
90: return;
91: Instance.GetType()
92: .GetProperties()
93: .Where(x => IsInjectable(x))
94: .ForEach<PropertyInfo>(x => Instance.SetProperty(x, CreateInstance(x)));
95: }
96:
97: #endregion
98:
99: #region IsInjectable
100:
101: private bool IsInjectable(MethodInfo Method)
102: {
103: return IsInjectable(Method.GetCustomAttributes(false));
104: }
105:
106: private bool IsInjectable(PropertyInfo Property)
107: {
108: return IsInjectable(Property.GetCustomAttributes(false));
109: }
110:
111: private bool IsInjectable(object[] Attributes)
112: {
113: return Attributes.OfType<Inject>().Count() > 0;
114: }
115:
116: #endregion
117:
118: #region CreateInstance
119:
120: private object CreateInstance(ConstructorInfo Constructor)
121: {
122: if (Constructor.IsNull() || MappingManager.IsNull())
123: return null;
124: List<object> ParameterValues = new List<object>();
125: Constructor.GetParameters().ForEach<ParameterInfo>(x => ParameterValues.Add(CreateInstance(x)));
126: return Constructor.Invoke(ParameterValues.ToArray());
127: }
128:
129: private object CreateInstance(ParameterInfo Parameter)
130: {
131: return CreateInstance(Parameter.GetCustomAttributes(false), Parameter.ParameterType);
132: }
133:
134: private object CreateInstance(PropertyInfo Property)
135: {
136: return CreateInstance(Property.GetCustomAttributes(false), Property.PropertyType);
137: }
138:
139: private object CreateInstance(object[] Attributes, Type Type)
140: {
141: if (Attributes.Length > 0)
142: {
143: foreach (Attribute Attribute in Attributes)
144: {
145: object TempObject = GetObject(Type, Attribute.GetType());
146: if (!TempObject.IsNull())
147: return TempObject;
148: }
149: }
150: return GetObject(Type);
151: }
152:
153: #endregion
154:
155: #region GetObject
156:
157: private object GetObject(Type Type)
158: {
159: IMapping Mapping = MappingManager.GetMapping(Type);
160: return Mapping.IsNull() ? null : Mapping.Implementation.Create();
161: }
162:
163: private object GetObject(Type Type, Type AttributeType)
164: {
165: IMapping Mapping = MappingManager.GetMapping(Type, AttributeType);
166: return Mapping.IsNull() ? null : Mapping.Implementation.Create();
167: }
168:
169: #endregion
170:
171: #endregion
172:
173: #region Properties
174:
175: /// <summary>
176: /// Mapping manager
177: /// </summary>
178: protected virtual MappingManager MappingManager { get; set; }
179:
180: #endregion
181: }
182: }