本文共 34860 字,大约阅读时间需要 116 分钟。
l 允許要求一個抽象物件或介面,ObjectBuilder會依據程式或組態檔的設定,傳回一個實體物件。 |
l 回傳一個既存物件,或是每次回傳一個新的物件(多半用於Dependency、Singleton情況,稍後會有詳細說明)。 |
l 透過特定的Factory建立一個物件,這個Factory可以依據組態檔的設定來建立物件(CustomFactory,隸屬於Enterprise Common Library)。 |
l 當物件擁有一個以上的建構子時,依據已有的參數,自動選取相容的建構子來建立要求的物件。(Consturctor Injection) |
l 允許物件於建立後,透過程式或組態檔來賦值至屬性,或是呼叫特定的函式。(Setter Injection、Interface Injection) |
l 提供一組Attribute,讓設計師可以指定需要Injection的屬性,亦或是於物件建立後需要呼叫的函式,也就是使用Reflection來自動完成Injection動作。 |
l 提供IBuilerAware介面,實作此介面的物件,ObjectBuilder會於建立該物件後,呼叫OnBuildUp或是OnTearDown函式。 |
l 提供TearDown機制,按建立物件的流程,反向釋放物件。 |
using System; using System.Collections.Generic; using System.Text; using Microsoft.Practices.ObjectBuilder; namespace SimpleApp { class Program { static void Main(string[] args) { Builder builder = new Builder(); TestObject obj = builder.BuildUp<TestObject>(new Locator(), null, null); obj.SayHello(); Console.ReadLine(); } } public class TestObject { public void SayHello() { Console.WriteLine("TEST"); } } } |
private StrategyList strategies = new StrategyList (); public BuilderBase() { } public PolicyList Policies { get { return policies; } } public StrategyList Strategies { get { return strategies; } } public Builder(IBuilderConfigurator<BuilderStage> configurator) { Strategies.AddNew<TypeMappingStrategy>(BuilderStage.PreCreation); Strategies.AddNew<SingletonStrategy>(BuilderStage.PreCreation); Strategies.AddNew<ConstructorReflectionStrategy>(BuilderStage.PreCreation); Strategies.AddNew<PropertyReflectionStrategy>(BuilderStage.PreCreation); Strategies.AddNew<MethodReflectionStrategy>(BuilderStage.PreCreation); Strategies.AddNew<CreationStrategy>(BuilderStage.Creation); Strategies.AddNew<PropertySetterStrategy>(BuilderStage.Initialization); Strategies.AddNew<MethodExecutionStrategy>(BuilderStage.Initialization); Strategies.AddNew<BuilderAwareStrategy>(BuilderStage.PostInitialization); Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy()); if (configurator != null) configurator.ApplyConfiguration(this); } |
public TTypeToBuild BuildUp ( IReadWriteLocator locator, string idToBuild, object existing, params PolicyList[] transientPolicies) { return (TTypeToBuild)BuildUp(locator, typeof(TTypeToBuild), idToBuild, existing, transientPolicies); } public virtual object BuildUp(IReadWriteLocator locator, Type typeToBuild, string idToBuild, object existing, params PolicyList[] transientPolicies) { .................... return DoBuildUp(locator, typeToBuild, idToBuild, existing, transientPolicies); ................... } private object DoBuildUp(IReadWriteLocator locator, Type typeToBuild, string idToBuild, object existing, PolicyList[] transientPolicies) { IBuilderStrategyChain chain = strategies.MakeStrategyChain(); .............. IBuilderContext context = MakeContext(chain, locator, transientPolicies); .......................... object result = chain.Head.BuildUp(context, typeToBuild, existing, idToBuild); ....................... } private IBuilderContext MakeContext(IBuilderStrategyChain chain, IReadWriteLocator locator, params PolicyList[] transientPolicies) { ............. return new BuilderContext(chain, locator, policies); } |
public Builder(IBuilderConfigurator<BuilderStage> configurator) { .................. Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy()); ................. } |
public override object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild) { if (existing != null) BuildUpExistingObject(context, typeToBuild, existing, idToBuild); else existing = BuildUpNewObject(context, typeToBuild, existing, idToBuild); return base.BuildUp(context, typeToBuild, existing, idToBuild); } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.SerializationFormatter)] private object BuildUpNewObject(IBuilderContext context, Type typeToBuild, object existing, string idToBuild) { ICreationPolicy policy = context.Policies.Get<ICreationPolicy>(typeToBuild, idToBuild); ......................... InitializeObject(context, existing, idToBuild, policy); return existing; } private void InitializeObject(IBuilderContext context, object existing, string id, ICreationPolicy policy) { ................ ConstructorInfo constructor = policy.SelectConstructor(context, type, id); ................... object[] parms = policy.GetParameters(context, type, id, constructor); ............... method.Invoke(existing, parms); } |
public class SingletonStrategy : BuilderStrategy { public override object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild) { DependencyResolutionLocatorKey key = new DependencyResolutionLocatorKey( typeToBuild, idToBuild); if (context.Locator != null && context.Locator.Contains(key, SearchMode.Local)) { TraceBuildUp(context, typeToBuild, idToBuild, ""); return context.Locator.Get(key); } return base.BuildUp(context, typeToBuild, existing, idToBuild); } } |
locator.Add("Test",new TestObject()); ............. TestObject obj = locator.Get<TestObject>("Test"); |
PS: ObjectBuidler 的 Locator 離完善的 Service Locator 還有段距離。 |
using System; using System.Collections.Generic; using System.Text; using System.Configuration; using Microsoft.Practices.ObjectBuilder; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; namespace OB_ConstructorInjectionTest { class Program { static void UseValueParameter(MyBuilderContext context) { ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new ValueParameter(typeof(IDataProcessor), new PromptDataProcessor())); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); } static void Main(string[] args) { MyBuilderContext context = new MyBuilderContext(new Locator()); context.InnerChain.Add(new CreationStrategy()); UseValueParameter(context); InputAccept accept = (InputAccept)context.HeadOfChain.BuildUp(context, typeof (InputAccept), null, null); accept.Execute(); Console.Read(); } } internal class MyBuilderContext : BuilderContext { public IReadWriteLocator InnerLocator; public BuilderStrategyChain InnerChain = new BuilderStrategyChain(); public PolicyList InnerPolicies = new PolicyList(); public LifetimeContainer lifetimeContainer = new LifetimeContainer(); public MyBuilderContext() : this(new Locator()) { } public MyBuilderContext(IReadWriteLocator locator) { InnerLocator = locator; SetLocator(InnerLocator); StrategyChain = InnerChain; SetPolicies(InnerPolicies); if (!Locator.Contains(typeof(ILifetimeContainer))) Locator.Add(typeof(ILifetimeContainer), lifetimeContainer); } } public class InputAccept { private IDataProcessor _dataProcessor; public void Execute() { Console.Write("Please Input some words:"); string input = Console.ReadLine(); input = _dataProcessor.ProcessData(input); Console.WriteLine(input); } public InputAccept(IDataProcessor dataProcessor) { _dataProcessor = dataProcessor; } } public interface IDataProcessor { string ProcessData(string input); } public class DummyDataProcessor : IDataProcessor { #region IDataProcessor Members public string ProcessData(string input) { return input; } #endregion } public class PromptDataProcessor : IDataProcessor { #region IDataProcessor Members public string ProcessData(string input) { return "your input is: " + input; } #endregion } } |
public ValueParameter(Type valueType, object value) |
static void UseDependencyParameter(MyBuilderContext context) { ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new DependencyParameter(typeof(IDataProcessor),null, typeof (PromptDataProcessor),NotPresentBehavior.CreateNew,SearchMode.Local)); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); ConstructorPolicy creationPolicy2 = new ConstructorPolicy(); context.Policies.Set<ICreationPolicy>(creationPolicy2, typeof(PromptDataProcessor),null); } |
public DependencyParameter(Type parameterType, string name, Type createType, NotPresentBehavior notPresentBehavior, SearchMode searchMode) |
public enum NotPresentBehavior { CreateNew, ReturnNull, Throw, } |
static void UseDependencyParameter(MyBuilderContext context) { context.InnerLocator.Add(new DependencyResolutionLocatorKey(typeof(IDataProcessor), null), new PromptDataProcessor()); ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new DependencyParameter(typeof(IDataProcessor), null ,typeof(PromptDataProcessor),NotPresentBehavior.CreateNew,SearchMode.Local)); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); ConstructorPolicy creationPolicy2 = new ConstructorPolicy(); context.Policies.Set<ICreationPolicy>(creationPolicy2, typeof(PromptDataProcessor),null); } |
static void UseDependencyParameter(MyBuilderContext context) { ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new DependencyParameter(typeof(IDataProcessor), null ,typeof(PromptDataProcessor),NotPresentBehavior.CreateNew,SearchMode.Local)); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); context.Policies.SetDefault<ICreationPolicy>(new ConstructorPolicy()); } |
static void UseCreationParameter(MyBuilderContext context) { ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new CreationParameter(typeof(IDataProcessor))); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); TypeMappingPolicy mappingPolicy = new TypeMappingPolicy(typeof(PromptDataProcessor), null); context.Policies.Set<ITypeMappingPolicy>(mappingPolicy, typeof(IDataProcessor), null); context.Policies.SetDefault<ICreationPolicy>(new ConstructorPolicy()); } static void Main(string[] args) { MyBuilderContext context = new MyBuilderContext(new Locator()); context.InnerChain.Add(new TypeMappingStrategy()); context.InnerChain.Add(new CreationStrategy()); UseCreationParameter(context); InputAccept accept = (InputAccept)context.HeadOfChain.BuildUp(context, typeof (InputAccept), null, null); accept.Execute(); Console.Read(); } |
public CloneParameter(IParameter param) |
public LookupParameter(object key) |
static void UseLookupParameter(MyBuilderContext context) { context.InnerLocator.Add("dataProcessor", new PromptDataProcessor()); ConstructorPolicy creationPolicy = new ConstructorPolicy(); creationPolicy.AddParameter(new LookupParameter("dataProcessor")); context.Policies.Set<ICreationPolicy>(creationPolicy, typeof(InputAccept), null); context.Policies.SetDefault<ICreationPolicy>(new ConstructorPolicy()); } |
static void UseInjectionConstructorAttribute(MyBuilderContext context) { context.InnerChain.Add(new ConstructorReflectionStrategy()); context.InnerChain.Add(new CreationStrategy()); } .......... public class InputAccept { private IDataProcessor _dataProcessor; public void Execute() { Console.Write("Please Input some words:"); string input = Console.ReadLine(); input = _dataProcessor.ProcessData(input); Console.WriteLine(input); } [InjectionConstructor] public InputAccept([Dependency(Name="dataProcessor", CreateType=typeof(PromptDataProcessor))]IDataProcessor dataProcessor) { _dataProcessor = dataProcessor; } } |
DependencyAttribute | DependencyParameter | 說明 |
Name | Name | id( 名稱 ) |
CreateType | CreateType | 欲建立物件的實體型別 |
NotPersentBehavior | NotPersentBehavior | 當欲建立物件無法由 Locator 取得時的行為模式。 |
SearchMode | SearchMode | 對 Locator 的搜尋法則。 |
static void UseDependencyResolution(MyBuilderContext context) { context.InnerChain.Add(new ConstructorReflectionStrategy()); context.InnerChain.Add(new CreationStrategy()); context.InnerLocator.Add(new DependencyResolutionLocatorKey(typeof(IDataProcessor), "dataProcessor" ),new PromptDataProcessor()); } [InjectionConstructor] public InputAccept([Dependency(Name="dataProcessor")]IDataProcessor dataProcessor) |
public ConstructorInfo SelectConstructor(IBuilderContext context, Type type, string id) { if (constructor != null) return constructor; List<Type> types = new List<Type>(); foreach (IParameter parm in parameters) types.Add(parm.GetParameterType(context)); return type.GetConstructor(types.ToArray()); } |
public object[] GetParameters(IBuilderContext context, Type type, string id, ConstructorInfo constructor) { ParameterInfo[] parms = constructor.GetParameters(); object[] parmsValueArray = new object[parms.Length]; for (int i = 0; i < parms.Length; ++i) parmsValueArray[i] = context.HeadOfChain.BuildUp(context, parms[i].ParameterType, null, id); return parmsValueArray; } |
static void UseMethodInfo(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new MethodExecutionStrategy()); IMethodCallInfo callInfo = new MethodCallInfo("SetDataProcessor", new ValueParameter(typeof(IDataProcessor), new PromptDataProcessor())); IMethodPolicy policy = new MethodPolicy(); policy.Methods.Add("SetDataProcessor", callInfo); context.Policies.Set<IMethodPolicy>(policy, typeof(InputAccept), null); } static void Main(string[] args) { MyBuilderContext context = new MyBuilderContext(new Locator()); UseDependencyAttribute(context); context.Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy()); InputAccept accept = (InputAccept)context.HeadOfChain.BuildUp(context, typeof(InputAccept), null , null); accept.Execute(); Console.Read(); } public class InputAccept { private IDataProcessor _dataProcessor; public void SetDataProcessor(IDataProcessor dataProcessor) { _dataProcessor = dataProcessor; } public void Execute() { Console.Write("Please Input some words:"); string input = Console.ReadLine(); input = _dataProcessor.ProcessData(input); Console.WriteLine(input); } } |
public MethodCallInfo(string methodName) public MethodCallInfo(string methodName, params object[] parameters) public MethodCallInfo(string methodName, params IParameter[] parameters) public MethodCallInfo(string methodName, IEnumerable<IParameter> parameters) public MethodCallInfo(MethodInfo method) public MethodCallInfo(MethodInfo method, params IParameter[] parameters) public MethodCallInfo(MethodInfo method, IEnumerable<IParameter> parameters) |
IMethodPolicy policy = context.Policies.Get<IMethodPolicy>(type, id); |
MethodInfo methodInfo = methodCallInfo.SelectMethod(context, type, id); |
object [] parameters = methodCallInfo.GetParameters(context, type, id, methodInfo); |
methodInfo.Invoke(obj, parameters); |
public MethodCallInfo(string methodName, params object[] parameters) :this(methodName, null, ObjectsToIParameters(parameters)) { } private static IEnumerable<IParameter> ObjectsToIParameters(object[] parameters) { List<IParameter> results = new List<IParameter>(); if (parameters != null) foreach (object parameter in parameters) results.Add(new ValueParameter(parameter.GetType(), parameter)); return results.ToArray(); } |
static void UseDependencyParameter(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new MethodExecutionStrategy()); MethodCallInfo callInfo = new MethodCallInfo("SetDataProcessor", new DependencyParameter(typeof(IDataProcessor), "dataProcessor", typeof(PromptDataProcessor), NotPresentBehavior.CreateNew, SearchMode.Local)); IMethodPolicy policy = new MethodPolicy(); policy.Methods.Add("SetDataProcessor", callInfo); context.Policies.Set<IMethodPolicy>(policy, typeof(InputAccept), null); } |
static void UseDependencyResolverLocator(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new MethodReflectionStrategy()); context.InnerChain.Add(new MethodExecutionStrategy()); context.InnerLocator.Add(new DependencyResolutionLocatorKey(typeof(IDataProcessor), "dataProcessor" ), new PromptDataProcessor()); } public class InputAccept { private IDataProcessor _dataProcessor; [InjectionMethod] public void SetDataProcessor( [Dependency(Name="dataProcessor"))] IDataProcessor dataProcessor) { _dataProcessor = dataProcessor; } ........... } |
static void UseDependencyAttribute(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new MethodReflectionStrategy()); context.InnerChain.Add(new MethodExecutionStrategy()); } public class InputAccept { private IDataProcessor _dataProcessor; [InjectionMethod] public void SetDataProcessor( [Dependency(Name="dataProcessor", CreateType=typeof(PromptDataProcessor))]IDataProcessor dataProcessor) { _dataProcessor = dataProcessor; } ............. } |
static void UsePropertySetter(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new PropertySetterStrategy()); PropertySetterPolicy policy = new PropertySetterPolicy(); policy.Properties.Add("DataProcessor", new PropertySetterInfo("DataProcessor", new ValueParameter(typeof(IDataProcessor), new PromptDataProcessor()))); context.Policies.Set<IPropertySetterPolicy>(policy, typeof(InputAccept), null); } static void Main(string[] args) { MyBuilderContext context = new MyBuilderContext(new Locator()); UsePropertySetter(context); context.Policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy()); InputAccept accept = (InputAccept)context.HeadOfChain.BuildUp(context, typeof (InputAccept), null, null); accept.Execute(); Console.Read(); } public class InputAccept { private IDataProcessor _dataProcessor; public IDataProcessor DataProcessor { get { return _dataProcessor; } set { _dataProcessor = value; } } public void Execute() { Console.Write("Please Input some words:"); string input = Console.ReadLine(); input = _dataProcessor.ProcessData(input); Console.WriteLine(input); } } |
public PropertySetterInfo(string name, IParameter value) public PropertySetterInfo(PropertyInfo propInfo, IParameter value) |
IPropertySetterPolicy policy = context.Policies.Get<IPropertySetterPolicy>(type, id); |
PropertyInfo propInfo = propSetterInfo.SelectProperty(context, type, id); |
object value = propSetterInfo.GetValue(context, type, id, propInfo); |
propInfo.SetValue(obj, value, null); |
static void UseDependencyParameter(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new PropertySetterStrategy()); PropertySetterPolicy policy = new PropertySetterPolicy(); policy.Properties.Add("DataProcessor", new PropertySetterInfo("DataProcessor", new DependencyParameter(typeof(IDataProcessor),"DataProcessor", typeof (PromptDataProcessor),NotPresentBehavior.CreateNew,SearchMode.Local))); context.Policies.Set<IPropertySetterPolicy>(policy, typeof(InputAccept), null); } |
static void UseDependencyResolutionLocator(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new PropertyReflectionStrategy()); context.InnerChain.Add(new PropertySetterStrategy()); context.Locator.Add(new DependencyResolutionLocatorKey(typeof(IDataProcessor), "DataProcessor" ), new PromptDataProcessor()); } public class InputAccept { private IDataProcessor _dataProcessor; [Dependency(Name="DataProcessor")] public IDataProcessor DataProcessor { get { return _dataProcessor; } set { _dataProcessor = value; } } ......... } |
static void UseDependencyAttribute(MyBuilderContext context) { context.InnerChain.Add(new CreationStrategy()); context.InnerChain.Add(new PropertyReflectionStrategy()); context.InnerChain.Add(new PropertySetterStrategy()); } public class InputAccept { private IDataProcessor _dataProcessor; [Dependency(Name="DataProcessor",CreateType=typeof(PromptDataProcessor))] public IDataProcessor DataProcessor { get { return _dataProcessor; } set { _dataProcessor = value; } } ............... } |
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1282150