博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[浪子学编程][MS Enterprise Library]ObjectBuilder之创建策略祥解(二)
阅读量:6096 次
发布时间:2019-06-20

本文共 8148 字,大约阅读时间需要 27 分钟。

ObjectBuilder之创建策略祥解()        

                                                                      Written by 浪子    

 

2、单件实例策略(SingletonStrategy):

 

       预备知识:

              在使用单件实例策略(SingletonStrategy),必需要先了解ObjectBuilder的另2个模块:

A、 定位器Locator:

关于定位器的原理及实现不在本文的讨论内容,请参考niwalker的专栏之

B、生存周期ILifetimeContainer:

LifetimeContainer主要用来跟踪对象的生存周期,负责对象的销毁动作。我们在这里只要将它当成一个简单的对象容器来用就可以了,类似Hashtable。

      

单件实例策略:

       策略方针:

      

       r_SingletonPolicy.png

None.gif
public 
class SingletonPolicy : ISingletonPolicy
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif   
private 
bool isSingleton;
InBlock.gif   
public SingletonPolicy(
bool isSingleton)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif   
dot.gif{
InBlock.gif      
this.isSingleton = isSingleton;
ExpandedSubBlockEnd.gif   }
InBlock.gif   
public 
bool IsSingleton
ExpandedSubBlockStart.gif
ContractedSubBlock.gif   
dot.gif{
ExpandedSubBlockStart.gif
ContractedSubBlock.gif      
get 
dot.gif
return isSingleton; }
ExpandedSubBlockEnd.gif   }
ExpandedBlockEnd.gif}
None.gif

可见SingletonPolicy很简单只是设置了一个标识。这个标识将在对象创建中决定是否采用单件实例策略

 

       单件策略:

 

      

r_SingletonStrategy.png

None.gif
public 
class SingletonStrategy : BuilderStrategy
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
public 
override 
object BuildUp(IBuilderContext context, Type typeToBuild, 
object existing, 
string idToBuild)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        DependencyResolutionLocatorKey key = 
new DependencyResolutionLocatorKey(typeToBuild, idToBuild);
InBlock.gif
InBlock.gif        
//
当前定位器不能为空,并且定位当前节点包含此对象
InBlock.gif
        
if (context.Locator != 
null && context.Locator.Contains(key, SearchMode.Local))
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            TraceBuildUp(context, typeToBuild, idToBuild, "");
InBlock.gif
InBlock.gif            
//
返回在定义器当前节点中key值符合的对象
InBlock.gif
            
return context.Locator.Get(key);
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
//
没有则,继续执行一步创建策略
InBlock.gif
        
return 
base.BuildUp(context, typeToBuild, existing, idToBuild);
InBlock.gif
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}

      

我想细心的你一定发现了,这里面跟TypeMappingStrategy中不一样的地方了:

SinglotenPolicy不见了?那是否SinglotenStrategy不需要具体方针呢?起初我也这样认为,后来发现错了。

我们将眼光跳到CreationStrategy,我发现对象创建完之后会执行RegisterObject,将对象注册到定位器&生存周期容器里面。

 

None.gif
private 
void RegisterObject(IBuilderContext context, Type typeToBuild, 
object existing, 
string idToBuild)
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
if (context.Locator != 
null)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        ILifetimeContainer lifetime = context.Locator.Get<ILifetimeContainer>(
typeof(ILifetimeContainer), SearchMode.Local);
InBlock.gif
InBlock.gif        
//
设置了对象生存周期容器
InBlock.gif
        
if (lifetime != 
null)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            SingletonPolicy singletonPolicy = context.Policies.Get<ISingletonPolicy>(typeToBuild, idToBuild);
InBlock.gif            
//
看这里用到了单件实例的具体方针,并确判断是否要启用单件实例
InBlock.gif
            
if (singletonPolicy != 
null && singletonPolicy.IsSingleton)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
//
注册到上下文的定位器
InBlock.gif
                context.Locator.Add(
new DependencyResolutionLocatorKey(typeToBuild, idToBuild), existing);
InBlock.gif
InBlock.gif                
//
注册到对象生存周期容器
InBlock.gif
                lifetime.Add(existing);
InBlock.gif                
if (TraceEnabled(context))
InBlock.gif                    TraceBuildUp(context, typeToBuild, idToBuild, Properties.Resources.SingletonRegistered);
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}

 

这里好像显得有点藕断丝连了,因为单件实例的策略方针跑到创建策略里面去起作用了:)。

    先不管是否是松耦合,不过也可以看出,ObjectBuilder对象的创建策略如何起作用都是通过各自相对的具体方针决定的。

 

应用实例:

 

我们还是利用的实例进行改造:

 

具体代码如下:

 

None.gif
using System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using Microsoft.Practices.ObjectBuilder;
None.gif
None.gif
namespace TestBuilder
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
class Program
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static 
void Main(
string[] args)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            IReadWriteLocator locator;
InBlock.gif            
InBlock.gif            Builder builder = 
new Builder();
InBlock.gif
InBlock.gif            PolicyList policyList = 
new PolicyList();
InBlock.gif
InBlock.gif            policyList.Set<ITypeMappingPolicy>(
new TypeMappingPolicy(
typeof(MyConcreteClass), "myclass"), 
typeof(MyAbstractClass), "myclass");
InBlock.gif            policyList.Set<ISingletonPolicy>(
new SingletonPolicy(
true), 
typeof(MyConcreteClass), "myclass");
InBlock.gif
InBlock.gif
InBlock.gif            locator = 
new Locator();
InBlock.gif            LifetimeContainer lifetime = 
new LifetimeContainer();
InBlock.gif            locator.Add( 
typeof(ILifetimeContainer),lifetime);
InBlock.gif
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            Console.WriteLine(" 第一次创建对象:");
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            
InBlock.gif            MyAbstractClass myclass = builder.BuildUp<MyAbstractClass>(locator, "myclass", 
null, policyList);
InBlock.gif
InBlock.gif            myclass.Base = "是我啊,还是我!";
InBlock.gif            Console.WriteLine(myclass.GetType().ToString());
InBlock.gif            Console.WriteLine(myclass.Base);
InBlock.gif
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            Console.WriteLine(" 第二次创建对象:");
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif
InBlock.gif            MyAbstractClass myclass2 = builder.BuildUp<MyAbstractClass>(locator, "myclass", 
null, policyList);
InBlock.gif            Console.WriteLine(myclass2.GetType().ToString());
InBlock.gif            Console.WriteLine(myclass2.Base);
InBlock.gif            Console.ReadLine();
InBlock.gif            
InBlock.gif            
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif
InBlock.gif    
public 
abstract 
class MyAbstractClass
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private 
string mBase;
InBlock.gif
InBlock.gif        
public 
string Base
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
get 
dot.gif
return 
this.mBase; }
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
set 
dot.gif
this.mBase = value; }
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public 
class MyConcreteClass : MyAbstractClass
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//
InBlock.gif
        
private 
string mTest;
InBlock.gif
InBlock.gif 
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
None.gif
None.gif
None.gif

 看到这里,我想你应该知道如何应用它,或者你也知道你能怎么去用它了。
 比如维护一个类似全局变量的对象集合?
    Updated @ 2006.07.04
   
最近在做Web MVP架构的搭建,准备使用ObjectBuilder来组织对象的创建.
重温了一下ObjectBuilder的单件策略.用自己的理解自己的语言总结了一下:
创建一个对象,并把他缓存起来(对象池,类似连接池),等下一次需要创建相同对象的时候,再把这个对象取出来,而不是重新创建一个.(此时有一个疑问,如果是引用类型的,旧对象中的修改是否会影响到后面再次利用的对象的值)

分类: ,,

ObjectBuilder之创建策略祥解()        

                                                                      Written by 浪子    

 

2、单件实例策略(SingletonStrategy):

 

       预备知识:

              在使用单件实例策略(SingletonStrategy),必需要先了解ObjectBuilder的另2个模块:

A、 定位器Locator:

关于定位器的原理及实现不在本文的讨论内容,请参考niwalker的专栏之

B、生存周期ILifetimeContainer:

LifetimeContainer主要用来跟踪对象的生存周期,负责对象的销毁动作。我们在这里只要将它当成一个简单的对象容器来用就可以了,类似Hashtable。

      

单件实例策略:

       策略方针:

      

       r_SingletonPolicy.png

None.gif
public 
class SingletonPolicy : ISingletonPolicy
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif   
private 
bool isSingleton;
InBlock.gif   
public SingletonPolicy(
bool isSingleton)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif   
dot.gif{
InBlock.gif      
this.isSingleton = isSingleton;
ExpandedSubBlockEnd.gif   }
InBlock.gif   
public 
bool IsSingleton
ExpandedSubBlockStart.gif
ContractedSubBlock.gif   
dot.gif{
ExpandedSubBlockStart.gif
ContractedSubBlock.gif      
get 
dot.gif
return isSingleton; }
ExpandedSubBlockEnd.gif   }
ExpandedBlockEnd.gif}
None.gif

可见SingletonPolicy很简单只是设置了一个标识。这个标识将在对象创建中决定是否采用单件实例策略

 

       单件策略:

 

      

r_SingletonStrategy.png

None.gif
public 
class SingletonStrategy : BuilderStrategy
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
public 
override 
object BuildUp(IBuilderContext context, Type typeToBuild, 
object existing, 
string idToBuild)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        DependencyResolutionLocatorKey key = 
new DependencyResolutionLocatorKey(typeToBuild, idToBuild);
InBlock.gif
InBlock.gif        
//
当前定位器不能为空,并且定位当前节点包含此对象
InBlock.gif
        
if (context.Locator != 
null && context.Locator.Contains(key, SearchMode.Local))
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            TraceBuildUp(context, typeToBuild, idToBuild, "");
InBlock.gif
InBlock.gif            
//
返回在定义器当前节点中key值符合的对象
InBlock.gif
            
return context.Locator.Get(key);
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        
//
没有则,继续执行一步创建策略
InBlock.gif
        
return 
base.BuildUp(context, typeToBuild, existing, idToBuild);
InBlock.gif
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}

      

我想细心的你一定发现了,这里面跟TypeMappingStrategy中不一样的地方了:

SinglotenPolicy不见了?那是否SinglotenStrategy不需要具体方针呢?起初我也这样认为,后来发现错了。

我们将眼光跳到CreationStrategy,我发现对象创建完之后会执行RegisterObject,将对象注册到定位器&生存周期容器里面。

 

None.gif
private 
void RegisterObject(IBuilderContext context, Type typeToBuild, 
object existing, 
string idToBuild)
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
if (context.Locator != 
null)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        ILifetimeContainer lifetime = context.Locator.Get<ILifetimeContainer>(
typeof(ILifetimeContainer), SearchMode.Local);
InBlock.gif
InBlock.gif        
//
设置了对象生存周期容器
InBlock.gif
        
if (lifetime != 
null)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            SingletonPolicy singletonPolicy = context.Policies.Get<ISingletonPolicy>(typeToBuild, idToBuild);
InBlock.gif            
//
看这里用到了单件实例的具体方针,并确判断是否要启用单件实例
InBlock.gif
            
if (singletonPolicy != 
null && singletonPolicy.IsSingleton)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
//
注册到上下文的定位器
InBlock.gif
                context.Locator.Add(
new DependencyResolutionLocatorKey(typeToBuild, idToBuild), existing);
InBlock.gif
InBlock.gif                
//
注册到对象生存周期容器
InBlock.gif
                lifetime.Add(existing);
InBlock.gif                
if (TraceEnabled(context))
InBlock.gif                    TraceBuildUp(context, typeToBuild, idToBuild, Properties.Resources.SingletonRegistered);
ExpandedSubBlockEnd.gif            }
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}

 

这里好像显得有点藕断丝连了,因为单件实例的策略方针跑到创建策略里面去起作用了:)。

    先不管是否是松耦合,不过也可以看出,ObjectBuilder对象的创建策略如何起作用都是通过各自相对的具体方针决定的。

 

应用实例:

 

我们还是利用的实例进行改造:

 

具体代码如下:

 

None.gif
using System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using Microsoft.Practices.ObjectBuilder;
None.gif
None.gif
namespace TestBuilder
ExpandedBlockStart.gif
ContractedBlock.gif
dot.gif{
InBlock.gif    
class Program
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
static 
void Main(
string[] args)
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
InBlock.gif            IReadWriteLocator locator;
InBlock.gif            
InBlock.gif            Builder builder = 
new Builder();
InBlock.gif
InBlock.gif            PolicyList policyList = 
new PolicyList();
InBlock.gif
InBlock.gif            policyList.Set<ITypeMappingPolicy>(
new TypeMappingPolicy(
typeof(MyConcreteClass), "myclass"), 
typeof(MyAbstractClass), "myclass");
InBlock.gif            policyList.Set<ISingletonPolicy>(
new SingletonPolicy(
true), 
typeof(MyConcreteClass), "myclass");
InBlock.gif
InBlock.gif
InBlock.gif            locator = 
new Locator();
InBlock.gif            LifetimeContainer lifetime = 
new LifetimeContainer();
InBlock.gif            locator.Add( 
typeof(ILifetimeContainer),lifetime);
InBlock.gif
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            Console.WriteLine(" 第一次创建对象:");
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            
InBlock.gif            MyAbstractClass myclass = builder.BuildUp<MyAbstractClass>(locator, "myclass", 
null, policyList);
InBlock.gif
InBlock.gif            myclass.Base = "是我啊,还是我!";
InBlock.gif            Console.WriteLine(myclass.GetType().ToString());
InBlock.gif            Console.WriteLine(myclass.Base);
InBlock.gif
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif            Console.WriteLine(" 第二次创建对象:");
InBlock.gif            Console.WriteLine("-----------------------");
InBlock.gif
InBlock.gif            MyAbstractClass myclass2 = builder.BuildUp<MyAbstractClass>(locator, "myclass", 
null, policyList);
InBlock.gif            Console.WriteLine(myclass2.GetType().ToString());
InBlock.gif            Console.WriteLine(myclass2.Base);
InBlock.gif            Console.ReadLine();
InBlock.gif            
InBlock.gif            
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif
InBlock.gif    
public 
abstract 
class MyAbstractClass
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private 
string mBase;
InBlock.gif
InBlock.gif        
public 
string Base
ExpandedSubBlockStart.gif
ContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
get 
dot.gif
return 
this.mBase; }
ExpandedSubBlockStart.gif
ContractedSubBlock.gif            
set 
dot.gif
this.mBase = value; }
ExpandedSubBlockEnd.gif        }
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    
public 
class MyConcreteClass : MyAbstractClass
ExpandedSubBlockStart.gif
ContractedSubBlock.gif    
dot.gif{
InBlock.gif        
//
InBlock.gif
        
private 
string mTest;
InBlock.gif
InBlock.gif 
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}
None.gif
None.gif
None.gif
None.gif
None.gif

 看到这里,我想你应该知道如何应用它,或者你也知道你能怎么去用它了。
 比如维护一个类似全局变量的对象集合?
    Updated @ 2006.07.04
   
最近在做Web MVP架构的搭建,准备使用ObjectBuilder来组织对象的创建.
重温了一下ObjectBuilder的单件策略.用自己的理解自己的语言总结了一下:
创建一个对象,并把他缓存起来(对象池,类似连接池),等下一次需要创建相同对象的时候,再把这个对象取出来,而不是重新创建一个.(此时有一个疑问,如果是引用类型的,旧对象中的修改是否会影响到后面再次利用的对象的值)

分类: , ,
本文转自浪子博客园博客,原文链接:http://www.cnblogs.com/walkingboy/archive/2006/04/29/IoC_ObjectBuilder_Singleton.html,如需转载请自行联系原作者
你可能感兴趣的文章
Tomcat与Spring中的事件机制详解
查看>>
Spark综合使用及用户行为案例区域内热门商品统计分析实战-Spark商业应用实战...
查看>>
初学者自学前端须知
查看>>
Retrofit 源码剖析-深入
查看>>
nodejs express
查看>>
企业级负载平衡简介(转)
查看>>
ICCV2017 论文浏览记录
查看>>
科技巨头的交通争夺战
查看>>
当中兴安卓手机遇上农行音频通用K宝 -- 卡在“正在通讯”,一直加载中
查看>>
Shell基础之-正则表达式
查看>>
JavaScript异步之Generator、async、await
查看>>
讲讲吸顶效果与react-sticky
查看>>
c++面向对象的一些问题1 0
查看>>
直播视频流技术名词
查看>>
iOS13-适配夜间模式/深色外观(Dark Mode)
查看>>
网易跟贴这么火,背后的某个力量不可忽视
查看>>
Java工程师学习指南初级篇
查看>>
华为朝向智能家庭!将从电视开始
查看>>
世界五大计算机程序员
查看>>
Android与Gradle(二):插件打包上传到Maven服务器
查看>>