[浪子学编程][MS Enterprise Library]ObjectBuilder之创建策略祥解(二)

简介:

ObjectBuilder之创建策略祥解()        

                                                                      Written by 浪子    

 

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

 

       预备知识:

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

A、 定位器Locator:

关于定位器的原理及实现不在本文的讨论内容,请参考niwalker的专栏之ObjectBuilder技术内幕Terrylee .NET设计模式(11):组合模式(Composite Pattern)

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.gifreturn 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.gifreturn  this.mBase; }
ExpandedSubBlockStart.gif ContractedSubBlock.gif             set  dot.gifthis.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的单件策略.用自己的理解自己的语言总结了一下:
创建一个对象,并把他缓存起来(对象池,类似连接池),等下一次需要创建相同对象的时候,再把这个对象取出来,而不是重新创建一个.(此时有一个疑问,如果是引用类型的,旧对象中的修改是否会影响到后面再次利用的对象的值)

分类: 浪子学编程,IoC / DI,1.首页原创精华.NET区123


ObjectBuilder之创建策略祥解()        

                                                                      Written by 浪子    

 

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

 

       预备知识:

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

A、 定位器Locator:

关于定位器的原理及实现不在本文的讨论内容,请参考niwalker的专栏之ObjectBuilder技术内幕Terrylee .NET设计模式(11):组合模式(Composite Pattern)

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.gifreturn 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.gifreturn  this.mBase; }
ExpandedSubBlockStart.gif ContractedSubBlock.gif             set  dot.gifthis.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,如需转载请自行联系原作者
目录
相关文章
win7-vs2012下安装.net frame work 的过程图文详解
win7-vs2012下安装.net frame work 的过程图文详解
win7-vs2012下安装.net frame work 的过程图文详解

热门文章

最新文章