利用标签(Attribute)和Microsoft.Practices.ObjectBuilder构造对象实例

1.定义attribute
 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace JasonNet.Platform.Common
 6{
 7    /// <summary>
 8    /// <see cref="DefaultImplementationAttribute"/>标签用于定义一个接口的默认实现类型。
 9    /// </summary>
10    /// Title: DefaultImplementationAttribute
11    /// Author: 姜辉
12    /// Version: 1.0
13    /// History:
14    ///     2006-07-13       姜辉    [创建]

15
16    [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
17    public sealed class DefaultImplementationAttribute : Attribute
18    {
19        private Type defaultImplementationType;
20        private string defaultImplementationTypeFullName;
21
22        /// <summary>
23        /// <see cref="DefaultImplementationAttribute"/>的构造函数。
24        /// </summary>
25        /// <param name="defaultImplementationType">指定接口的默认实现类型</param>

26        public DefaultImplementationAttribute(Type defaultImplementationType)
27        {
28            this.defaultImplementationType = defaultImplementationType;
29        }

30
31        /// <summary>
32        /// <see cref="DefaultImplementationAttribute"/>的构造函数。
33        /// </summary>
34        /// <param name="defaultImplementationTypeFullName">指定接口的默认实现类型的字符串表达形式</param>

35        public DefaultImplementationAttribute(string defaultImplementationTypeFullName)
36        {
37            this.defaultImplementationTypeFullName = defaultImplementationTypeFullName;
38        }

39
40        /// <summary>
41        /// 指定接口的默认实现类型。
42        /// </summary>

43        public Type DefaultImplementationType
44        {
45            get
46            {
47                return defaultImplementationType;
48            }

49        }

50
51        /// <summary>
52        /// 指定接口的默认实现类型的字符串表达形式。
53        /// </summary>

54        public string DefaultImplementationTypeFullName
55        {
56            get
57            {
58                return defaultImplementationTypeFullName;
59            }

60        }

61    }

62}

2.定义构造容器
  1using System;
  2using System.IO;
  3using System.Globalization;
  4using System.Collections.Generic;
  5using System.Text;
  6using System.Reflection;
  7using Microsoft.Practices.ObjectBuilder;
  8
  9using JasonNet.Platform.Common.Properties;
 10
 11namespace JasonNet.Platform.Common
 12{
 13    /// <summary>
 14    /// <see cref="ObjectContainer"/>用于创建、获取容器中的对象实例。
 15    /// Title: ObjectContainer
 16    /// Author: 姜辉
 17    /// Version: 1.0
 18    /// History:
 19    ///     2006-07-13 姜辉 [创建]

 20 
 21    public static class ObjectContainer
 22    {
 23        private static IBuilder<BuilderStage> builder = new Builder();
 24        private static Locator locator =  new Locator();
 25
 26        private const string InterfacePrefix = "I";
 27        private const string AbstractClassPrefix = "Base";
 28        private const string DefaultImplNamespaceSuffix = "DefaultImpl.";
 29
 30        /// <summary>
 31        /// 根据指定的对象类型构造对象实例。
 32        /// </summary>
 33        /// <remarks>
 34        /// <para>
 35        /// <see cref="ObjectContainer"/>不支持简单值类型的构造,因此,如果<typeparamref name="T"/>是简单值类型,
 36        /// 将抛出<see cref="ArgumentException"/>
 37        /// </para>
 38        /// <para>
 39        /// 如果<typeparamref name="T"/>是非静态的实现类,则直接构建<typeparamref name="T"/>的对象实例。
 40        /// </para>
 41        /// <para>
 42        /// 如果<typeparamref name="T"/>是接口或抽象类,则<see cref="ObjectContainer"/>将按以下规则来创建该接口
 43        /// 或抽象类的实现类对象实例:
 44        /// <list type="bullet">
 45        /// <item>
 46        /// <description>
 47        /// 首先检测<typeparamref name="T"/>是否标记了<see cref="DefaultImplementationAttribute"/>标签来指定默认
 48        /// 的实现类,如果指定了合法的默认实现类,则会构造出指定的默认实现类的对象实例;如果通过标签指定的默认实
 49        /// 现类不合法,则会抛出<see cref="TypeNotMatchException"/><see cref="DefaultImplementationNotFoundException"/>异常。
 50        /// </description>
 51        /// </item>
 52        /// <item>
 53        /// <description>
 54        /// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现
 55        /// 类,则会根据<c>JasonNet</c>平台默认的匹配关系(默认实现类的命名空间为接口命名空间 + ".DefaultImpl",
 56        /// 类名为接口名称去掉前缀“I”,或基类名称去掉“Base”)来查找默认实现类,如果能够找到,则构造出该默认
 57        /// 实现类的对象实例,如果无法找到,则抛出<see cref="DefaultImplementationNotFoundException"/>异常。
 58        /// </description>
 59        /// </item>
 60        /// </list>
 61        /// </para>
 62        /// <para>
 63        /// 从以上对于接口或抽象类的默认实现对象的构造规则中可以看出,要成功构造一个接口或抽象类的默认实现类对象
 64        /// ,需要满足以下任意一项:
 65        /// <list type="number">
 66        /// <item>
 67        /// <description><typeparamref name="T"/>使用<see cref="DefaultImplementationAttribute"/>进行了正确的
 68        /// 配置,即<see cref="DefaultImplementationAttribute"/>指定的默认实现类确实实现了<typeparamref name="T"/>
 69        /// 接口或抽象类。</description>
 70        /// </item>
 71        /// <item>
 72        /// <description>
 73        /// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现
 74        /// 类,则要求<typeparamref name="T"/>接口或抽象类、以及默认实现类的命名都遵循以下规范:1,接口必须以<c>
 75        /// I</c>作前缀,抽象类必须以<c>Base</c>作前缀;2,默认实现类的命名空间为接口命名空间 + ".DefaultImpl";
 76        /// 3,默认实现类的名称为接口名称去掉前缀“I”,或抽象类的名称去掉前缀“Base”,如下例所示:
 77        /// </description>
 78        /// </item>
 79        /// </list>
 80        /// <example>
 81        /// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置接口与其默认实现类的示例,该情况下使用本
 82        /// 方法传入IUserManager接口可以构造出UserManager的实例。
 83        /// <code>
 84        /// namespace JasonNet.Platform.Security
 85        /// {
 86        ///     [DefaultImplementation(typeof(JasonNet.Platform.Security.UserManager))]
 87        ///     public interface IUserManager {}
 88        /// }
 89        /// 
 90        /// namespace JasonNet.Platform.Security
 91        /// {
 92        ///     public class UserManager : IUserManager {}
 93        /// }
 94        /// </code>
 95        /// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置抽象类与其默认实现类的示例,该情况下使用
 96        /// 本方法传入BizLogDatabaseAdapter抽象类可以构造出基于SQL Server实现的SqlBizLogDatabaseAdapter的实例。
 97        /// <code>
 98        /// namespace JasonNet.Platform.Logging.Database
 99        /// {
100        ///     [DefaultImplementation(typeof(JaonNet.Platform.Logging.Database.SqlBizLogDatabaseAdapter))]
101        ///     public abstract class BizLogDatabaseAdapter {}
102        /// }
103        /// 
104        /// namespace JasonNet.Platform.Logging.Database
105        /// {
106        ///     public class SqlBizLogDatabaseAdapter : BizLogDatabaseAdapter {}
107        /// }
108        /// </code>
109        /// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的接口与其默认实现类的示例,该情况下使用本方法传入
110        /// IUserManager接口可以构造出UserManager的实例。
111        /// <code>
112        /// namespace JasonNet.Platform.Security
113        /// {
114        ///     public interface IUserManager {}
115        /// }
116        /// 
117        /// namespace JasonNet.Platform.Security.DefaultImpl
118        /// {
119        ///     public class UserManager : IUserManager {}
120        /// }
121        /// </code>
122        /// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的抽象类与其默认实现类的示例,该情况下使用本方法传入
123        /// BaseBizLogDatabaseAdapter抽象类可以构造出BizLogDatabaseAdapter的实例。
124        /// <code>
125        /// namespace JasonNet.Platform.Logging.Database
126        /// {
127        ///     public abstract class BaseBizLogDatabaseAdapter {}
128        /// }
129        /// 
130        /// namespace JasonNet.Platform.Logging.Database.DefaultImpl
131        /// {
132        ///     public class BizLogDatabaseAdapter : BaseBizLogDatabaseAdapter {}
133        /// }
134        /// </code>
135        /// 以下是按<c>JasonNet</c>平台为解决工程间循环引用实现类的示例,该情况下使用本方法传入
136        /// 指定接口的默认实现类型的字符串表达形式来构造出其实例。
137        /// <code>
138        /// namespace *****.****.DE.InnerInterfaces 
139        /// {
140        /// [DefaultImplementation("*****.****.DE.DE.BusinessLogic.DesignProxyServiceFacade,*****.****.DE.BusinessLogic")]
141        /// public interface IDeDeInnerInterface
142        ///  {
143        ///  IList<String> GetDesignCompanyByProjectNo(string projectNo);
144        ///  }
145        /// }
146        /// namespace *****.****.**.DE.InnerInterfaces  
147        /// {
148        /// public interface IDesignProxyServiceFacade : IDeDeInnerInterface
149        /// {
150        ///  此处回到配置接口与其默认实现类的示例
151        /// }
152        /// </code>
153        /// </example>
154        /// </para>
155        /// <para>
156        /// 对于以上各种情况的实现类对象实例的创建,默认情况下,都将使用实现类的第一个构造函数来构造对象实例,
157        /// 如果第一个构造函数中含有参数,则对于简单值类型以该类型的默认值为参数值;对于对象类型,会在容器中去
158        /// 查找是否已经有该类型的对象存在,如果存在,则用该对象作为参数值,如果不存在则构造一个新的该类型的对
159        /// 象作为参数值(在构造该类型的对象时如果又需要参数,则类似地按上述步骤进行,即一层层地递归往下找,直
160        /// 到所有的依赖对象都被构造后,该对象才会被构造)。由于带参数的构造方式非常复杂,强烈建议使用不带参数
161        /// 的构造函数来构造对象,即始终把不带参数的构造函数放在代码的最前面。
162        /// </para>
163        /// </remarks>
164        /// <typeparam name="T">要构造的对象的类型</typeparam>
165        /// <returns>构造的对象实例</returns>
166        /// <exception cref="ArgumentException">
167        /// 当<typeparamref name="T"/>是简单值类型、或在T(或T的默认实现类)中无法找到构造所需的构造函数时抛出
168        /// 的异常。</exception>
169        /// <exception cref="TypeNotMatchException">
170        /// 当<typeparamref name="T"/>上的<see cref="DefaultImplementationAttribute"/>标签所指定的默认实现类类
171        /// 型与<typeparamref name="T"/>不匹配(并没有实现T或从T派生)时抛出的异常。</exception>
172        /// <exception cref="DefaultImplementationNotFoundException">
173        /// 当通过平台默认的匹配关系无法找到<typeparamref name="T"/>的默认实现类时所抛出的异常。
174        /// </exception>

175        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design""CA1004:GenericMethodsShouldProvideTypeParameter")]
176        public static T BuildUp<T>()
177        {
178            return (T)BuildUp(typeof(T));
179        }

180
181        internal static object BuildUp(Type typeToBuild)
182        {
183            Type reflectionType = null;
184
185            // typeToBuild 如果是值类型或者静态类时
186            if (typeToBuild.IsValueType || (typeToBuild.IsAbstract && typeToBuild.IsSealed))
187            {
188                throw new ArgumentException(
189                    String.Format(CultureInfo.CurrentUICulture,
190                    Resources.ExceptionTypeIsValueTypeOrStaticClass, typeToBuild.Name));
191            }

192
193            // typeToBuild是接口或抽象类
194            if (typeToBuild.IsAbstract)
195            {
196                object[] defaultImplAttrs = typeToBuild.GetCustomAttributes(typeof(DefaultImplementationAttribute), false);
197                if (defaultImplAttrs.Length == 0)
198                {
199                    // 没有标签,按照默认规则寻找
200
201                    // 如果类型的命名不符合规范,则抛出异常
202                    if (!typeToBuild.Name.StartsWith(ObjectContainer.InterfacePrefix) &&
203                        !typeToBuild.Name.StartsWith(ObjectContainer.AbstractClassPrefix))
204                    {
205                        throw new IllegalTypeNameException(new string[] { typeToBuild.FullName });
206                    }

207
208                    StringBuilder defaultImplTypeString = new StringBuilder();
209                    defaultImplTypeString.Append(typeToBuild.FullName.Substring(0, typeToBuild.FullName.LastIndexOf("."+ 1));
210                    defaultImplTypeString.Append(DefaultImplNamespaceSuffix);
211
212                    if (typeToBuild.IsInterface)
213                    {
214                        // 接口名称去掉前缀“I”
215                        defaultImplTypeString.Append(typeToBuild.Name.Substring(1));
216                    }

217                    else
218                    {
219                        //抽象类的名称去掉前缀“Base”
220                        defaultImplTypeString.Append(typeToBuild.Name.Substring(4));
221                    }

222                    defaultImplTypeString.Append("");
223                    defaultImplTypeString.Append(typeToBuild.Assembly.FullName);
224
225                    reflectionType = SearchForTypeToBuild(defaultImplTypeString.ToString());
226
227                    // 当没有找到默认实现类
228                    // 或者找到的是仍然是接口或者抽象类时
229                    if (reflectionType == null ||
230                        !typeToBuild.IsAssignableFrom(reflectionType) ||
231                        reflectionType.IsAbstract ||
232                        reflectionType.IsInterface)
233                    {
234                        throw new DefaultImplementationNotFoundException(new string[] { typeToBuild.FullName });
235                    }

236                }

237                else
238                {
239                    // 有标签
240                    DefaultImplementationAttribute defImpl = defaultImplAttrs[0as DefaultImplementationAttribute;
241
242                    if (!String.IsNullOrEmpty(defImpl.DefaultImplementationTypeFullName))
243                    {
244                        reflectionType = SearchForTypeToBuild(defImpl.DefaultImplementationTypeFullName);
245                    }

246                    else
247                    {
248                        reflectionType = defImpl.DefaultImplementationType;
249                    }

250
251                    // 标签所指定的默认实现类类型与typeToBuild不匹配(并没有实现typeToBuild或从typeToBuild派生)
252                    // 或者默认的实现也是一个接口或抽象类
253                    if (reflectionType == null)
254                    {
255                        throw new DefaultImplementationNotFoundException(new string[] { typeToBuild.FullName });
256                    }

257                    if (reflectionType == typeToBuild ||
258                        !typeToBuild.IsAssignableFrom(reflectionType) ||
259                        reflectionType.IsAbstract ||
260                        reflectionType.IsInterface)
261                    {
262                        throw new TypeNotMatchException();
263                    }

264                }

265
266                return builder.BuildUp(locator, reflectionType, nullnull);
267            }

268            else
269            {
270                // T是非静态的实现类时,检查其是否具有有效的构造函数
271                if (typeToBuild.GetConstructors().Length == 0)
272                {
273                    throw new ArgumentException(
274                        String.Format(CultureInfo.CurrentUICulture, 
275                        Resources.ExceptionTypeHasNoConstructors, typeToBuild.Name));
276                }

277
278                return builder.BuildUp(locator, typeToBuild,nullnull);
279            }

280        }

281
282        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design""CA1031:DoNotCatchGeneralExceptionTypes")]
283        private static Type SearchForTypeToBuild(string defaultImplTypeString)
284        {
285            Type reflectedType = null;
286
287            try
288            {
289                reflectedType = Type.GetType(defaultImplTypeString);
290            }

291            catch
292            {
293            }

294            return reflectedType;
295        }

296    }

297}

298
posted @ 2007-08-31 09:53  中尉  阅读(472)  评论(0编辑  收藏  举报