SingletonProvider 实现代码
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Reflection;
5
6
namespace 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, null, null, null) as T;
22
}
23
return _Instance;
24
}
25
}
26
27
private static T _Instance;
28
}
29
30
}
31
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Reflection;5

6
namespace AIO.DesignPattern.Singleton7
{8
public sealed class SingletonProvider<T> where T : class9
{10
static SingletonProvider()11
{12
}13

14
public static T Instance15
{16
get17
{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, null, null, null) as T;22
}23
return _Instance;24
}25
}26

27
private static T _Instance;28
}29

30
}31

取消采用第20行是因为'Activator.CreateInstance<T>()'调用必须实现Public的构造函数
采用现在方式有两种好处:一是将构造函数声明为私有或受保护避免多种方式调用,另一种方式是将构造函数声明为公有使得既可以单件又可以多件使用(本人觉得有时候很有用,尤其是代码作为类库时)
线程安全版本代码如下:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Reflection;
5
6
namespace 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, null, null, null) as T;
26
}
27
return _Instance;
28
}
29
}
30
}
31
32
private static T _Instance;
33
}
34
}
35
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Reflection;5

6
namespace AIO.DesignPattern.Singleton7
{8
public sealed class ThreadSafeSingletonProvider<T> where T : class9
{10
static ThreadSafeSingletonProvider()11
{12
}13

14
static private object syncObj = new object();15

16
public static T Instance17
{18
get19
{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, null, null, null) as T;26
}27
return _Instance;28
}29
}30
}31

32
private static T _Instance;33
}34
}35

单元测试代码如下:
1
using Microsoft.VisualStudio.TestTools.UnitTesting;
2
using System;
3
using System.Text;
4
using System.Collections.Generic;
5
using AIO.DesignPattern.Singleton;
6
namespace 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
using Microsoft.VisualStudio.TestTools.UnitTesting;2
using System;3
using System.Text;4
using System.Collections.Generic;5
using AIO.DesignPattern.Singleton;6
namespace AIO.UnitTest7
{8
[TestClass()]9
public class SingletonProviderTest10
{11
public class SingleInstanceClass12
{13
public SingleInstanceClass()14
{15
_count++;16
}17

18
public static SingleInstanceClass Instance19
{20
get21
{22
return SingletonProvider<SingleInstanceClass>.Instance;23
}24
}25

26
public static int Count27
{28
get29
{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 Test47
/// </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


浙公网安备 33010602011771号