利用標籤(Attribute)和Microsoft.Practices.ObjectBuilder構造對象實例

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

    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章