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

来源:互联网 发布:php soap 传json 编辑:程序博客网 时间:2024/04/30 03:56

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

    }

}