Bolik‘s AIO Blog
All In One Team Blog

SingletonProvider 实现代码

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Reflection;
 5
 6namespace AIO.DesignPattern.Singleton
 7{
 8  public sealed class SingletonProvider<T> where T : class
 9  {
10    static SingletonProvider()
11    {
12    }

13
14    public static T Instance
15    {
16      get
17      {
18        if (_Instance == null)
19        {
20          //_Instance = Activator.CreateInstance<T>();
21          _Instance = typeof(T).InvokeMember(typeof(T).Name, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, nullnullnullas T;
22        }

23        return _Instance;
24      }

25    }

26
27    private static T _Instance;
28  }

29
30}

31

取消采用第20行是因为'Activator.CreateInstance<T>()'调用必须实现Public的构造函数

采用现在方式有两种好处:一是将构造函数声明为私有或受保护避免多种方式调用,另一种方式是将构造函数声明为公有使得既可以单件又可以多件使用(本人觉得有时候很有用,尤其是代码作为类库时)

线程安全版本代码如下:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Reflection;
 5
 6namespace AIO.DesignPattern.Singleton
 7{
 8  public sealed class ThreadSafeSingletonProvider<T> where T : class
 9  {
10    static ThreadSafeSingletonProvider()
11    {
12    }

13
14    static private object syncObj = new object();
15
16    public static T Instance
17    {
18      get
19      {
20        lock (syncObj)
21        {
22          if (_Instance == null)
23          {
24            //_instance = Activator.CreateInstance<T>();
25            _Instance = typeof(T).InvokeMember(typeof(T).Name, BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, nullnullnullas T;
26          }

27          return _Instance;
28        }

29      }

30    }

31
32    private static T _Instance;
33  }

34}

35

 

单元测试代码如下:

 1using Microsoft.VisualStudio.TestTools.UnitTesting;
 2using System;
 3using System.Text;
 4using System.Collections.Generic;
 5using AIO.DesignPattern.Singleton;
 6namespace AIO.UnitTest
 7{
 8    [TestClass()]
 9    public class SingletonProviderTest
10    {
11        public class SingleInstanceClass
12        {
13            public SingleInstanceClass()
14            {
15                _count++;
16            }

17
18            public static SingleInstanceClass Instance
19            {
20                get
21                {
22                    return SingletonProvider<SingleInstanceClass>.Instance;
23                }

24            }

25
26            public static int Count
27            {
28                get
29                {
30                    return _count;
31                }

32            }

33
34            public static void DoStatic()
35            {
36            }

37
38            public void DoInstance()
39            {
40            }

41
42            private static int _count = 0;
43        }

44
45        /// <summary>
46        /// SingletonProvider  Test
47        /// </summary>

48        [TestMethod()]
49        public void InstanceTest()
50        {
51            Assert.AreEqual(SingleInstanceClass.Count, 0);
52
53            SingleInstanceClass.DoStatic();
54            Assert.AreEqual(SingleInstanceClass.Count, 0);
55
56            SingleInstanceClass.Instance.DoInstance();
57            Assert.AreEqual(SingleInstanceClass.Count, 1);
58
59            SingleInstanceClass.DoStatic();
60            Assert.AreEqual(SingleInstanceClass.Count, 1);
61
62            SingleInstanceClass.Instance.DoInstance();
63            Assert.AreEqual(SingleInstanceClass.Count, 1);
64
65            SingleInstanceClass.DoStatic();
66            Assert.AreEqual(SingleInstanceClass.Count, 1);
67        }

68    }

69}

70

 

应用代码简单到只有一行如下:

SingletonProvider<SomeClass>.Instance.doSomething();

ok 今天就到这里 有时间会将其扩展实现单件/多件扩展的 Provide(Pooling FixedSize MaxSize etc.)

If you have all DesignPattern's Provider, you'll look the technology is just simple!

the Art of programing

posted on 2006-05-10 14:50  Bolik  阅读(372)  评论(0编辑  收藏  举报