[浪子学编程][MS Enterprise Library]ObjectBuilder之创建策略祥解(一)
ObjectBuilder之创建策略祥解(一)
-Written by 浪子 [walkingboy.cnblogs.com]
前言:
ObjectBuilder已经默认制定了很多创建策略,可能看到这么多策略加上整个地方架构满天飞,反而搞不清楚如何去应用ObjectBuilder创建我们需要的对象了。研究它的原理只是为了更好的发挥它的功效,本系列将详细解析ObjectBuilder中的所有默认创建策略的原理以及应用:
1、类型映射策略(TypeMappingStrategy):
上文 讲过,策略的具体行为都是由他们各自所对应的方针来决定的。类型映射策略也有其映射方针:
方针规范(ITypeMappingPolicy):
public interface ITypeMappingPolicy : IBuilderPolicy
{
/// <summary>
/// Maps one Type/ID pair to another.
/// </summary>
/// <param name="incomingTypeIDPair">The incoming Type/ID pair.</param>
/// <returns>The new Type/ID pair.返回映射后的对象类型&标识</returns>
DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair);
}
{
/// <summary>
/// Maps one Type/ID pair to another.
/// </summary>
/// <param name="incomingTypeIDPair">The incoming Type/ID pair.</param>
/// <returns>The new Type/ID pair.返回映射后的对象类型&标识</returns>
DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair);
}
具体方针(TypeMappingPolicy):
public class TypeMappingPolicy : ITypeMappingPolicy
{
private DependencyResolutionLocatorKey pair;
/// <summary>
/// Initializes a new instance of the <see cref="TypeMappingPolicy"/> class using
/// the provided type and ID.
/// </summary>
/// <param name="type">要翻译的对象类型</param>
/// <param name="id">The new ID to be returned during Map.</param>
public TypeMappingPolicy(Type type, string id)
{
pair = new DependencyResolutionLocatorKey(type, id);
}
/// <summary>
/// See <see cref="ITypeMappingPolicy.Map"/> for more information.
/// </summary>
public DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair)
{
return pair;
}
}
{
private DependencyResolutionLocatorKey pair;
/// <summary>
/// Initializes a new instance of the <see cref="TypeMappingPolicy"/> class using
/// the provided type and ID.
/// </summary>
/// <param name="type">要翻译的对象类型</param>
/// <param name="id">The new ID to be returned during Map.</param>
public TypeMappingPolicy(Type type, string id)
{
pair = new DependencyResolutionLocatorKey(type, id);
}
/// <summary>
/// See <see cref="ITypeMappingPolicy.Map"/> for more information.
/// </summary>
public DependencyResolutionLocatorKey Map(DependencyResolutionLocatorKey incomingTypeIDPair)
{
return pair;
}
}
创建策略中的类型映射应用:
public override object BuildUp(IBuilderContext context, Type t, object existing, string id)
{
//要创建的对象类型DependencyResolutionLocatorKey
DependencyResolutionLocatorKey result = new DependencyResolutionLocatorKey(t, id);
//按照创建的对象类型和标识查询上下文中的映射方针
ITypeMappingPolicy policy = context.Policies.Get<ITypeMappingPolicy>(t, id);
if (policy != null)
{
//将方针中的翻译对象映射给result
result = policy.Map(result);
//记录BuildUp日志
TraceBuildUp(context, t, id, Properties.Resources.TypeMapped, result.Type, result.ID ?? "(null)");
//检测是否能正常转换这两个类型
Guard.TypeIsAssignableFromType(t, result.Type, t);
}
//用方针中的具体翻译类型result.Type替换原来要创建的对象类型t,将修改后的创建责任推给下一个节点
return base.BuildUp(context, result.Type, existing, result.ID);
}
{
//要创建的对象类型DependencyResolutionLocatorKey
DependencyResolutionLocatorKey result = new DependencyResolutionLocatorKey(t, id);
//按照创建的对象类型和标识查询上下文中的映射方针
ITypeMappingPolicy policy = context.Policies.Get<ITypeMappingPolicy>(t, id);
if (policy != null)
{
//将方针中的翻译对象映射给result
result = policy.Map(result);
//记录BuildUp日志
TraceBuildUp(context, t, id, Properties.Resources.TypeMapped, result.Type, result.ID ?? "(null)");
//检测是否能正常转换这两个类型
Guard.TypeIsAssignableFromType(t, result.Type, t);
}
//用方针中的具体翻译类型result.Type替换原来要创建的对象类型t,将修改后的创建责任推给下一个节点
return base.BuildUp(context, result.Type, existing, result.ID);
}
应用举例:
class Program
{
static void Main(string[] args)
{
//创建builder 实例
Builder builder = new Builder();
PolicyList policyList = new PolicyList();
//创建自己的映射方针,目标类型typeof(MyConcreteClass),被翻译类型typeof(MyAbstractClass),标识"myclass"
policyList.Set<ITypeMappingPolicy>(new TypeMappingPolicy(typeof(MyConcreteClass), null), typeof(MyAbstractClass), "myclass");
MyAbstractClass myclass = builder.BuildUp<MyAbstractClass>(null, "myclass", null, policyList);
Console.WriteLine(myclass.GetType().ToString());
Console.ReadLine();
}
}
//抽象基类
public abstract class MyAbstractClass
{
//抽象类具体定义
}
//具体实现类
public class MyConcreteClass : MyAbstractClass
{
//具体类个性化的定义
private string test;
}
{
static void Main(string[] args)
{
//创建builder 实例
Builder builder = new Builder();
PolicyList policyList = new PolicyList();
//创建自己的映射方针,目标类型typeof(MyConcreteClass),被翻译类型typeof(MyAbstractClass),标识"myclass"
policyList.Set<ITypeMappingPolicy>(new TypeMappingPolicy(typeof(MyConcreteClass), null), typeof(MyAbstractClass), "myclass");
MyAbstractClass myclass = builder.BuildUp<MyAbstractClass>(null, "myclass", null, policyList);
Console.WriteLine(myclass.GetType().ToString());
Console.ReadLine();
}
}
//抽象基类
public abstract class MyAbstractClass
{
//抽象类具体定义
}
//具体实现类
public class MyConcreteClass : MyAbstractClass
{
//具体类个性化的定义
private string test;
}
我们可以看到结果会输出:
MyConcreteClass
可见我们通过指定方针就可以轻松的将抽象类或者接口类映射成为具体的实例类,而且这种转换是安全的
//检测是否能正常转换这两个类型
Guard.TypeIsAssignableFromType(t, result.Type, t);
Guard.TypeIsAssignableFromType(t, result.Type, t);