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

原创 2007年09月23日 21:39:00

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, nullnull);
            }

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


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

        }


        [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;
        }

    }

}


javascript原型对象、构造函数和实例对象

大家都知道,javascript中其实并没有类的概念。但是,用构造函数跟原型对象却可以模拟类的实现。在这里,就先很不严谨的使用类这个词,以方便说明。 下面整理了一些关于javascript的构造函数...
  • linn721
  • linn721
  • 2014年03月08日 17:35
  • 1975

JS面向对象-原型对象,实例对象,构造函数的关系

JS中每创建一个函数,该函数就会自动拥有一个prototype属性,为什么那??  因为最根上的object拥有一个prototype属性,而js中所有的对象又都继承自object,所以js中所有的对...
  • u014205965
  • u014205965
  • 2015年05月17日 22:30
  • 2941

完整原型链详细图解(构造函数、原型、实例化对象)

一、首先说一下什么是构造函数: 构造函数:用来在创建对象时初始化对象。特点:构造函数名一般为大写字母开头;与new运算符一起使用来实例化对象。 举例: function Person(){} ...
  • SpicyBoiledFish
  • SpicyBoiledFish
  • 2017年05月03日 14:28
  • 1456

C#里面Attribute的使用方法

这篇文章主要讲一下C#里面Attribute的使用方法 比如你把玩家的血量、攻击、防御等属性写到枚举里面。然后界面可能有很多地方要根据这个枚举获取属性的描述文本。 比如你做网络框架的时候,一个协议号对...
  • wangch2012
  • wangch2012
  • 2016年02月13日 10:55
  • 1298

如何创建没有new能实例化的构造函数

众所周知,在js里是没有真正的类这个饿概念的(以后的版本会加入),通常我们所谓的类就是用new来构造实例的普通函数。 通常实例化一个构造函数的时候,里面的this是指向被实例化的实例的。如下示例所示...
  • fendouzhe123
  • fendouzhe123
  • 2015年01月22日 12:56
  • 1098

一个对象的实例化过程【重点】

一、过程  Person p = new Person();  1,JVM会去读取指定路径下的Person.class文件,并加载进内存,    并会先加载Person的父类(如果有直接父类的情况下)...
  • u012986057
  • u012986057
  • 2016年01月23日 16:41
  • 928

C++学习之对象成员篇

对象成员特点总结: (1)实例化对象A时,如果对象A有对象成员B,那么先执行对象B的构造函数,再执行A的构造函数。 (2)如果对象A中有对象成员B,那么销毁对象A时,先执行对象A的析构函数,再执行B的...
  • hudfang
  • hudfang
  • 2016年01月13日 16:21
  • 380

构造器创建对象

构造器是创建对象的重要途径 问题:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 答:不是的。构造器是创建Java对象的重要途径,通过new关键字调用构造器时,构造...
  • zz276203200
  • zz276203200
  • 2016年07月19日 10:25
  • 726

构造函数、实例和原型的概念和关系

每个函数都属于对象,都会有一个属性叫prototype。这个属性指向一个对象,我们把他叫做当前函数的原型对象。原型对象下面有个属性叫constructor.这个属性指向当前函数。函数又分为普通函数和构...
  • beautifull001
  • beautifull001
  • 2016年12月16日 17:16
  • 995

HTML标签中的attribute和DOM对象

HTML标签中的attribute和DOM对象的property是比较容易混淆的两个概念,实际上这二者对于理解”文档对象模型”是十分重要的。通常我们会把HTML标签的attribute译为”特性”而把...
  • u012402926
  • u012402926
  • 2016年04月20日 17:55
  • 721
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用标签(Attribute)和Microsoft.Practices.ObjectBuilder构造对象实例
举报原因:
原因补充:

(最多只允许输入30个字)