ObjectBuilder中提供了很多Policy,甚至还可以按自己的需要任意扩展,那对于已经提供的Policy,我们应该如何正确的使用呢?这篇文章我会先介绍一下其中的SingletonPolicy。
在我们实际的项目开发中,经常会遇到多次创建同一个类的情况,如果按照一般的方法去new一个类,那么每new一次,就会产生一个实例,对于小型系统完全没有问题,但当系统比较庞大时,就应该认真思考了。
FrankFei at 2007/08/01
ObjectBuilder中提供了很多Policy,甚至还可以按自己的需要任意扩展,那对于已经提供的Policy,我们应该如何正确的使用呢?这篇文章我会先介绍一下其中的SingletonPolicy。
在我们实际的项目开发中,经常会遇到多次创建同一个类的情况,如果按照一般的方法去new一个类,那么每new一次,就会产生一个实例,对于小型系统完全没有问题,但当系统比较庞大时,就应该认真思考了。
先给大家看一个下面的例子,其中的MyConcreteClass是一个实体类,同时要加上using Microsoft.Practices.ObjectBuilder;。
static void Main(string[] args)
![]()
![]()
{
![]()
IReadWriteLocator locator;
![]()
![]()
Builder builder = new Builder();
![]()
![]()
PolicyList policyList = new PolicyList();
![]()
![]()
ISingletonPolicy singletonPolicy =new SingletonPolicy(true);
![]()
policyList.Set<ISingletonPolicy>(singletonPolicy, typeof(MyConcreteClass), "MyClassId");
![]()
locator = new Locator();
![]()
LifetimeContainer lifetime = new LifetimeContainer();
![]()
locator.Add(typeof(ILifetimeContainer), lifetime);
![]()
MyConcreteClass myConcreteClass1 = builder.BuildUp<MyConcreteClass>(locator, "MyClassId", null, policyList);
![]()
MyConcreteClass myConcreteClass2 = builder.BuildUp<MyConcreteClass>(locator, "MyClassId", null, policyList);
![]()
}
![]()
![]()
上面写了那么多,在很大程度上和MyConcreteClass myConcreteClass1=new MyConcreteClass();MyConcreteClass myConcreteClass2=new MyConcreteClass();差不多,那为什么要搞得这么复杂呢?现在我们假设MyConcreteClass中有一个字段:public int age,我们把上面的代码改成如下:
static void Main(string[] args)
![]()
![]()
{
![]()
IReadWriteLocator locator;
![]()
![]()
Builder builder = new Builder();
![]()
![]()
PolicyList policyList = new PolicyList();
![]()
![]()
ISingletonPolicy singletonPolicy =new SingletonPolicy(true);
![]()
policyList.Set<ISingletonPolicy>(singletonPolicy, typeof(MyConcreteClass), "MyClassId");
![]()
locator = new Locator();
![]()
LifetimeContainer lifetime = new LifetimeContainer();
![]()
locator.Add(typeof(ILifetimeContainer), lifetime);
![]()
MyConcreteClass myConcreteClass1 = builder.BuildUp<MyConcreteClass>(locator, "MyClassId", null, policyList);
![]()
myConcreteClass1.age=28;
![]()
MyConcreteClass myConcreteClass2 = builder.BuildUp<MyConcreteClass>(locator, "MyClassId", null, policyList);
![]()
Console.WriteLine(myConcreteClass2.age.ToString());
![]()
}
![]()
![]()
运行上面的代码,我们发现myConcreteClass2.age.ToString()也是28,由此可见myConcreteClass1和myConcreteClass2它们其实是同一个实例(即Singleton模式已经生效)。所以在使用SingletonPolicy时对于引用类型要清楚上面的情况,以便正确使用。
对于细心的读者可能会提出这样一个问题,那如果我有两个类MyConcreteClass和MyConcreteClass1,它们都继承于MyAbstractClass,那我是不是要把上面的代码Copy一份,然后把其中所有的MyConcreteClass改为MyConcreteClass1呢?虽然可以那样做,但显然不是好的方法,所以在ObjectBuilder中又引入了一个Policy:TypeMappingPolicy,下面是使用TypeMappingPolicy后的代码:
static void Main(string[] args)
![]()
![]()
{
![]()
IReadWriteLocator locator;
![]()
![]()
Builder builder = new Builder();
![]()
![]()
PolicyList policyList = new PolicyList();
![]()
ITypeMappingPolicy typeMappingPolicy=new TypeMappingPolicy(typeof(MyConcreteClass),"MyClassId");
![]()
ISingletonPolicy singletonPolicy =new SingletonPolicy(true);
![]()
policyList.Set<ITypeMappingPolicy>(typeMappingPolicy, typeof(MyAbstractClass), "MyClassId");
![]()
policyList.Set<ISingletonPolicy>(singletonPolicy, typeof(MyAbstractClass), "MyClassId");
![]()
locator = new Locator();
![]()
LifetimeContainer lifetime = new LifetimeContainer();
![]()
locator.Add(typeof(ILifetimeContainer), lifetime);
![]()
MyAbstractClass myConcreteClass1 = builder.BuildUp<MyAbstractClass>(locator, "MyClassId", null, policyList);
![]()
MyAbstractClass myConcreteClass2 = builder.BuildUp<MyAbstractClass>(locator, "MyClassId", null, policyList);
![]()
}
![]()
![]()
现在如果我要创建MyConcreteClass1,只要把上面的ITypeMappingPolicy typeMappingPolicy=new TypeMappingPolicy(typeof(MyConcreteClass),"MyClassId");改为ITypeMappingPolicy typeMappingPolicy=new TypeMappingPolicy(typeof(MyConcreteClass1),"MyClassId");即可,这样是不是在某种程度上更符合面向对象的一些原则呢!
关于TypeMappingPolicy和SingletonPolicy就说到这里,以上只是我个人的理解,不当之处请指教!