1.定义ATTRIBUTE using System; using System.Collections.Generic; using System.Text; namespace JasonNet.Platform.Common ... { /**//// <summary> /// <see cref="DefaultImplementationAttribute"/>标签用于定义一个接口的默认实现类型。 /// </summary> /// Title: DefaultImplementationAttribute /// Author: 姜辉 /// Version: 1.0 /// History: /// 2006-07-13 姜辉 [创建] [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class DefaultImplementationAttribute : Attribute ...{ private Type defaultImplementationType; private string defaultImplementationTypeFullName; /**//// <summary> /// <see cref="DefaultImplementationAttribute"/>的构造函数。 /// </summary> /// <param name="defaultImplementationType">指定接口的默认实现类型</param> public DefaultImplementationAttribute(Type defaultImplementationType) ...{ this.defaultImplementationType = defaultImplementationType; } /**//// <summary> /// <see cref="DefaultImplementationAttribute"/>的构造函数。 /// </summary> /// <param name="defaultImplementationTypeFullName">指定接口的默认实现类型的字符串表达形式</param> public DefaultImplementationAttribute(string defaultImplementationTypeFullName) ...{ this.defaultImplementationTypeFullName = defaultImplementationTypeFullName; } /**//// <summary> /// 指定接口的默认实现类型。 /// </summary> public Type DefaultImplementationType ...{ get ...{ return defaultImplementationType; } } /**//// <summary> /// 指定接口的默认实现类型的字符串表达形式。 /// </summary> public string DefaultImplementationTypeFullName ...{ get ...{ return defaultImplementationTypeFullName; } } }} 2.定义构造容器类 using System; using System.IO; using System.Globalization; using System.Collections.Generic; using System.Text; using System.Reflection; using Microsoft.Practices.ObjectBuilder; using JasonNet.Platform.Common.Properties; namespace JasonNet.Platform.Common ... { /**//// <summary> /// <see cref="ObjectContainer"/>用于创建、获取容器中的对象实例。 /// Title: ObjectContainer /// Author: 姜辉 /// Version: 1.0 /// History: /// 2006-07-13 姜辉 [创建] public static class ObjectContainer ...{ private static IBuilder<BuilderStage> builder = new Builder(); private static Locator locator = new Locator(); private const string InterfacePrefix = "I"; private const string AbstractClassPrefix = "Base"; private const string DefaultImplNamespaceSuffix = "DefaultImpl."; /**//// <summary> /// 根据指定的对象类型构造对象实例。 /// </summary> /// <remarks> /// <para> /// <see cref="ObjectContainer"/>不支持简单值类型的构造,因此,如果<typeparamref name="T"/>是简单值类型, /// 将抛出<see cref="ArgumentException"/>。 /// </para> /// <para> /// 如果<typeparamref name="T"/>是非静态的实现类,则直接构建<typeparamref name="T"/>的对象实例。 /// </para> /// <para> /// 如果<typeparamref name="T"/>是接口或抽象类,则<see cref="ObjectContainer"/>将按以下规则来创建该接口 /// 或抽象类的实现类对象实例: /// <list type="bullet"> /// <item> /// <description> /// 首先检测<typeparamref name="T"/>是否标记了<see cref="DefaultImplementationAttribute"/>标签来指定默认 /// 的实现类,如果指定了合法的默认实现类,则会构造出指定的默认实现类的对象实例;如果通过标签指定的默认实 /// 现类不合法,则会抛出<see cref="TypeNotMatchException"/>或<see cref="DefaultImplementationNotFoundException"/>异常。 /// </description> /// </item> /// <item> /// <description> /// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现 /// 类,则会根据<c>JasonNet</c>平台默认的匹配关系(默认实现类的命名空间为接口命名空间 + ".DefaultImpl", /// 类名为接口名称去掉前缀“I”,或基类名称去掉“Base”)来查找默认实现类,如果能够找到,则构造出该默认 /// 实现类的对象实例,如果无法找到,则抛出<see cref="DefaultImplementationNotFoundException"/>异常。 /// </description> /// </item> /// </list> /// </para> /// <para> /// 从以上对于接口或抽象类的默认实现对象的构造规则中可以看出,要成功构造一个接口或抽象类的默认实现类对象 /// ,需要满足以下任意一项: /// <list type="number"> /// <item> /// <description>对<typeparamref name="T"/>使用<see cref="DefaultImplementationAttribute"/>进行了正确的 /// 配置,即<see cref="DefaultImplementationAttribute"/>指定的默认实现类确实实现了<typeparamref name="T"/> /// 接口或抽象类。</description> /// </item> /// <item> /// <description> /// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现 /// 类,则要求<typeparamref name="T"/>接口或抽象类、以及默认实现类的命名都遵循以下规范:1,接口必须以<c> /// I</c>作前缀,抽象类必须以<c>Base</c>作前缀;2,默认实现类的命名空间为接口命名空间 + ".DefaultImpl"; /// 3,默认实现类的名称为接口名称去掉前缀“I”,或抽象类的名称去掉前缀“Base”,如下例所示: /// </description> /// </item> /// </list> /// <example> /// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置接口与其默认实现类的示例,该情况下使用本 /// 方法传入IUserManager接口可以构造出UserManager的实例。 /// <code> /// namespace JasonNet.Platform.Security /// { /// [DefaultImplementation(typeof(JasonNet.Platform.Security.UserManager))] /// public interface IUserManager {} /// } /// /// namespace JasonNet.Platform.Security /// { /// public class UserManager : IUserManager {} /// } /// </code> /// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置抽象类与其默认实现类的示例,该情况下使用 /// 本方法传入BizLogDatabaseAdapter抽象类可以构造出基于SQL Server实现的SqlBizLogDatabaseAdapter的实例。 /// <code> /// namespace JasonNet.Platform.Logging.Database /// { /// [DefaultImplementation(typeof(JaonNet.Platform.Logging.Database.SqlBizLogDatabaseAdapter))] /// public abstract class BizLogDatabaseAdapter {} /// } /// /// namespace JasonNet.Platform.Logging.Database /// { /// public class SqlBizLogDatabaseAdapter : BizLogDatabaseAdapter {} /// } /// </code> /// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的接口与其默认实现类的示例,该情况下使用本方法传入 /// IUserManager接口可以构造出UserManager的实例。 /// <code> /// namespace JasonNet.Platform.Security /// { /// public interface IUserManager {} /// } /// /// namespace JasonNet.Platform.Security.DefaultImpl /// { /// public class UserManager : IUserManager {} /// } /// </code> /// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的抽象类与其默认实现类的示例,该情况下使用本方法传入 /// BaseBizLogDatabaseAdapter抽象类可以构造出BizLogDatabaseAdapter的实例。 /// <code> /// namespace JasonNet.Platform.Logging.Database /// { /// public abstract class BaseBizLogDatabaseAdapter {} /// } /// /// namespace JasonNet.Platform.Logging.Database.DefaultImpl /// { /// public class BizLogDatabaseAdapter : BaseBizLogDatabaseAdapter {} /// } /// </code> /// 以下是按<c>JasonNet</c>平台为解决工程间循环引用实现类的示例,该情况下使用本方法传入 /// 指定接口的默认实现类型的字符串表达形式来构造出其实例。 /// <code> /// namespace *****.****.DE.InnerInterfaces /// { /// [DefaultImplementation("*****.****.DE.DE.BusinessLogic.DesignProxyServiceFacade,*****.****.DE.BusinessLogic")] /// public interface IDeDeInnerInterface /// { /// IList<String> GetDesignCompanyByProjectNo(string projectNo); /// } /// } /// namespace *****.****.**.DE.InnerInterfaces /// { /// public interface IDesignProxyServiceFacade : IDeDeInnerInterface /// { /// 此处回到配置接口与其默认实现类的示例 /// } /// </code> /// </example> /// </para> /// <para> /// 对于以上各种情况的实现类对象实例的创建,默认情况下,都将使用实现类的第一个构造函数来构造对象实例, /// 如果第一个构造函数中含有参数,则对于简单值类型以该类型的默认值为参数值;对于对象类型,会在容器中去 /// 查找是否已经有该类型的对象存在,如果存在,则用该对象作为参数值,如果不存在则构造一个新的该类型的对 /// 象作为参数值(在构造该类型的对象时如果又需要参数,则类似地按上述步骤进行,即一层层地递归往下找,直 /// 到所有的依赖对象都被构造后,该对象才会被构造)。由于带参数的构造方式非常复杂,强烈建议使用不带参数 /// 的构造函数来构造对象,即始终把不带参数的构造函数放在代码的最前面。 /// </para> /// </remarks> /// <typeparam name="T">要构造的对象的类型</typeparam> /// <returns>构造的对象实例</returns> /// <exception cref="ArgumentException"> /// 当<typeparamref name="T"/>是简单值类型、或在T(或T的默认实现类)中无法找到构造所需的构造函数时抛出 /// 的异常。</exception> /// <exception cref="TypeNotMatchException"> /// 当<typeparamref name="T"/>上的<see cref="DefaultImplementationAttribute"/>标签所指定的默认实现类类 /// 型与<typeparamref name="T"/>不匹配(并没有实现T或从T派生)时抛出的异常。</exception> /// <exception cref="DefaultImplementationNotFoundException"> /// 当通过平台默认的匹配关系无法找到<typeparamref name="T"/>的默认实现类时所抛出的异常。 /// </exception> [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] public static T BuildUp<T>() ...{ return (T)BuildUp(typeof(T)); } internal static object BuildUp(Type typeToBuild) ...{ Type reflectionType = null; // typeToBuild 如果是值类型或者静态类时 if (typeToBuild.IsValueType || (typeToBuild.IsAbstract && typeToBuild.IsSealed)) ...{ throw new ArgumentException( String.Format(CultureInfo.CurrentUICulture, Resources.ExceptionTypeIsValueTypeOrStaticClass, typeToBuild.Name)); } // typeToBuild是接口或抽象类 if (typeToBuild.IsAbstract) ...{ object[] defaultImplAttrs = typeToBuild.GetCustomAttributes(typeof(DefaultImplementationAttribute), false); if (defaultImplAttrs.Length == 0) ...{ // 没有标签,按照默认规则寻找 // 如果类型的命名不符合规范,则抛出异常 if (!typeToBuild.Name.StartsWith(ObjectContainer.InterfacePrefix) && !typeToBuild.Name.StartsWith(ObjectContainer.AbstractClassPrefix)) ...{ throw new IllegalTypeNameException(new string[] ...{ typeToBuild.FullName }); } StringBuilder defaultImplTypeString = new StringBuilder(); defaultImplTypeString.Append(typeToBuild.FullName.Substring(0, typeToBuild.FullName.LastIndexOf(".") + 1)); defaultImplTypeString.Append(DefaultImplNamespaceSuffix); if (typeToBuild.IsInterface) ...{ // 接口名称去掉前缀“I” defaultImplTypeString.Append(typeToBuild.Name.Substring(1)); } else ...{ //抽象类的名称去掉前缀“Base” defaultImplTypeString.Append(typeToBuild.Name.Substring(4)); } defaultImplTypeString.Append(", "); defaultImplTypeString.Append(typeToBuild.Assembly.FullName); reflectionType = SearchForTypeToBuild(defaultImplTypeString.ToString()); // 当没有找到默认实现类 // 或者找到的是仍然是接口或者抽象类时 if (reflectionType == null || !typeToBuild.IsAssignableFrom(reflectionType) || reflectionType.IsAbstract || reflectionType.IsInterface) ...{ throw new DefaultImplementationNotFoundException(new string[] ...{ typeToBuild.FullName }); } } else ...{ // 有标签 DefaultImplementationAttribute defImpl = defaultImplAttrs[0] as DefaultImplementationAttribute; if (!String.IsNullOrEmpty(defImpl.DefaultImplementationTypeFullName)) ...{ reflectionType = SearchForTypeToBuild(defImpl.DefaultImplementationTypeFullName); } else ...{ reflectionType = defImpl.DefaultImplementationType; } // 标签所指定的默认实现类类型与typeToBuild不匹配(并没有实现typeToBuild或从typeToBuild派生) // 或者默认的实现也是一个接口或抽象类 if (reflectionType == null) ...{ throw new DefaultImplementationNotFoundException(new string[] ...{ typeToBuild.FullName }); } if (reflectionType == typeToBuild || !typeToBuild.IsAssignableFrom(reflectionType) || reflectionType.IsAbstract || reflectionType.IsInterface) ...{ throw new TypeNotMatchException(); } } return builder.BuildUp(locator, reflectionType, null, null); } else ...{ // T是非静态的实现类时,检查其是否具有有效的构造函数 if (typeToBuild.GetConstructors().Length == 0) ...{ throw new ArgumentException( String.Format(CultureInfo.CurrentUICulture, Resources.ExceptionTypeHasNoConstructors, typeToBuild.Name)); } return builder.BuildUp(locator, typeToBuild, null, null); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] private static Type SearchForTypeToBuild(string defaultImplTypeString) ...{ Type reflectedType = null; try ...{ reflectedType = Type.GetType(defaultImplTypeString); } catch ...{ } return reflectedType; } }}