0%

首先给出项目的结构

IPublish.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 发布事件基础接口 5 ///

6 public interface IPublish 7 {
8 string PublishTag { get; set; }
9 object PublishData { get; set; } 10 } 11 }

复制代码

IPubSubCenter.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 订阅发布中心基础接口 5 ///

6 public interface IPubSubCenter 7 {
8 ///
9 /// 订阅事件 10 ///

11 bool AddSubscribe(string tag, Func<ISubscribe, object, object> method, object data, string name); 12 bool AddSubscribe(string tag, Func<ISubscribe, object, object> method, string name); 13 bool AddSubscribe(Subscribe subscribe); 14 ///
15 /// 获得指定事件的订阅列表 16 ///

17 SubscribeList GetSubscribeList(string tag); 18 ///
19 /// 获得订阅 20 ///

21 Subscribe GetSubscribe(string tag, string name); 22 ///
23 /// 删除订阅 24 ///

25 void RemoveSubscribe(string tag, string name); 26
27 ///
28 /// 发布事件 29 ///

30 IEnumerable Publish(string tag, object data); 31 IEnumerable Publish(string tag); 32 IEnumerable Publish(Publish publish); 33 } 34 }

复制代码

ISubscribe.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 订阅事件基础接口 5 ///

6 public interface ISubscribe 7 {
8 ///
9 /// 订阅的事件 10 ///

11 string SubscribeTag { get; set; } 12 ///
13 /// 订阅的名称 14 ///

15 string SubscribeName { get; set; } 16 ///
17 /// 响应发布时传递的参数 18 ///

19 object Data { get; set; } 20 ///
21 /// 响应发布的方法 22 ///

23 Func<ISubscribe, object, object> SubscribeMethod { get; set; } 24 ///
25 /// 调用订阅方法 26 ///

27 object Invoke(object val); 28 } 29 }

复制代码

Publish.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 发布事件基类 5 ///

6 public class Publish : IPublish 7 {
8 private string _publishTag; 9 private object _publishData; 10
11 public Publish() 12 { 13 } 14
15 public Publish(string tag) 16 : this(tag, new object()) 17 { 18
19 } 20
21 public Publish(string tag, object val) 22 { 23 _publishTag = tag; 24 _publishData = val; 25 } 26
27 public string PublishTag 28 { 29 get
30 { 31 return _publishTag; 32 } 33 set
34 { 35 _publishTag = value; 36 } 37 } 38
39 public object PublishData 40 { 41 get
42 { 43 return _publishData; 44 } 45 set
46 { 47 _publishData = value; 48 } 49 } 50 } 51 }

复制代码

PubSubCenter.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 订阅发布中心基类 5 ///

6 public class PubSubCenter : IPubSubCenter 7
8 {
9 private Dictionary<string, SubscribeList> _pubsubList = new Dictionary<string, SubscribeList>();
10
11 public bool AddSubscribe(string tag, Func<ISubscribe, object, object> method, object data ,string name) 12 {
13 Subscribe subscribe = new Subscribe(); 14 subscribe.Data = data; 15 subscribe.SubscribeMethod = method; 16 subscribe.SubscribeTag = tag; 17 subscribe.SubscribeName = name; 18 return AddSubscribe(subscribe); 19 }
20
21 public bool AddSubscribe(string tag, Func<ISubscribe, object, object> method, string name) 22 {
23 return AddSubscribe(tag, method, new object(),name);
24 }
25
26 public bool AddSubscribe(Subscribe subscribe) 27 {
28 if (subscribe == null)
29 {
30 return false;
31 }
32 else
33 {
34 if (String.IsNullOrEmpty(subscribe.SubscribeName)) 35 {
36 return false;
37 }
38 Subscribe subscribet = GetSubscribe(subscribe.SubscribeTag, subscribe.SubscribeName); 39 if (subscribet != null)
40 {
41 return false;
42 }
43 else
44 {
45 if (_pubsubList.ContainsKey(subscribe.SubscribeTag)) 46 {
47 _pubsubList[subscribe.SubscribeTag].Add(subscribe);
48 }
49 else
50 {
51 SubscribeList list = new SubscribeList(); 52 list.Add(subscribe);
53 _pubsubList.Add(subscribe.SubscribeTag, list);
54 }
55 return true;
56 }
57 }
58 }
59
60 public SubscribeList GetSubscribeList(string tag) 61 {
62 if (_pubsubList.ContainsKey(tag)) 63 {
64 return _pubsubList[tag]; 65 }
66 else
67 {
68 return new SubscribeList(); 69 }
70 }
71
72 public Subscribe GetSubscribe(string tag, string name) 73 {
74 if (_pubsubList.ContainsKey(tag)) 75 {
76 foreach (Subscribe item in _pubsubList[tag]) 77 {
78 if (item.SubscribeName == name) 79 {
80 return item; 81 }
82 }
83 return null;
84 }
85 else
86 {
87 return null;
88 }
89 }
90
91 public void RemoveSubscribe(string tag, string name) 92 {
93 Subscribe subscribe = GetSubscribe(tag, name); 94 _pubsubList[tag].Remove(subscribe);
95 }
96
97 public IEnumerable<object> Publish(string tag, object data) 98 {
99 if (_pubsubList.ContainsKey(tag)) 100 { 101 foreach (Subscribe item in _pubsubList[tag]) 102 { 103 yield return item.Invoke(data); 104 } 105 } 106 else
107 { 108 yield break; 109 } 110 } 111
112 public IEnumerable<object> Publish(string tag) 113 { 114 return Publish(tag, new object()); 115 } 116
117 public IEnumerable<object> Publish(Publish publish) 118 { 119 return Publish(publish.PublishTag, publish.PublishData); 120 } 121 } 122 }

复制代码

Subscribe.cs源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 订阅事件基类 5 ///

6 public class Subscribe : ISubscribe 7 {
8 private object _data; 9 private Func<ISubscribe, object, object> _subscribeMethod; 10 private string _subscribeTag; 11 private string _subscribeName; 12
13 public Subscribe() 14 { 15 } 16
17 public Subscribe(string tag, Func<ISubscribe, object, object> method) 18 : this(tag, method, “”) 19 { 20
21 } 22
23 public Subscribe(string tag, Func<ISubscribe, object, object> method, object data) 24 : this(tag, method, data, “”) 25 { 26
27 } 28
29 public Subscribe(string tag, Func<ISubscribe, object, object> method,string name) 30 : this(tag, method, new object(), name) 31 { 32
33 } 34
35 public Subscribe(string tag, Func<ISubscribe, object, object> method, object data,string name) 36 { 37 _data = data; 38 _subscribeTag = tag; 39 _subscribeMethod = method; 40 _subscribeName = name; 41 } 42
43 public object Data 44 { 45 get
46 { 47 return _data; 48 } 49 set
50 { 51 _data = value; 52 } 53 } 54
55 public Func<ISubscribe, object, object> SubscribeMethod 56 { 57 get
58 { 59 return _subscribeMethod; 60 } 61 set
62 { 63 _subscribeMethod = value; 64 } 65 } 66
67 public object Invoke(object val) 68 { 69 return SubscribeMethod(this, val); 70 } 71
72 public string SubscribeTag 73 { 74 get
75 { 76 return _subscribeTag; 77 } 78 set
79 { 80 _subscribeTag = value; 81 } 82 } 83
84 public string SubscribeName 85 { 86 get
87 { 88 return _subscribeName; 89 } 90 set
91 { 92 _subscribeName = value; 93 } 94 } 95 } 96 }

复制代码

SubscribeList.cs的源码:

复制代码

1 namespace NsWebChat.PublishSubscribe 2 {
3 ///


4 /// 订阅列表 5 ///

6 public class SubscribeList : IList
7 {
8 private List subscribes = new List();
9
10 public int IndexOf(Subscribe item) 11 { 12 return subscribes.IndexOf(item); 13 } 14
15 public void Insert(int index, Subscribe item) 16 { 17 subscribes.Insert(index, item); 18 } 19
20 public void RemoveAt(int index) 21 { 22 subscribes.RemoveAt(index); 23 } 24
25 public Subscribe this[int index] 26 { 27 get
28 { 29 return subscribes[index]; 30 } 31 set
32 { 33 subscribes[index] = value; 34 } 35 } 36
37 public void Add(Subscribe item) 38 { 39 subscribes.Add(item); 40 } 41
42 public void Clear() 43 { 44 subscribes.Clear(); 45 } 46
47 public bool Contains(Subscribe item) 48 { 49 return subscribes.Contains(item); 50 } 51
52 public void CopyTo(Subscribe[] array, int arrayIndex) 53 { 54 subscribes.CopyTo(array, arrayIndex); 55 } 56
57 public int Count 58 { 59 get
60 { 61 return subscribes.Count; 62 } 63 } 64
65 public bool IsReadOnly 66 { 67 get { return false; } 68 } 69
70 public bool Remove(Subscribe item) 71 { 72 return subscribes.Remove(item); 73 } 74
75 public IEnumerator GetEnumerator() 76 { 77 return subscribes.GetEnumerator(); 78 } 79
80 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 81 { 82 return subscribes.GetEnumerator(); 83 } 84 } 85 }

复制代码

下面是单元测试的源码(PubSubCenterTest.cs):

复制代码

1 namespace WebChatUnitTest 2 {
3 [TestClass]
4 public class PubSubCenterTest 5 {
6 public object Test1(ISubscribe subscribe, object data) 7 {
8 Assert.IsTrue(subscribe.Data == data); 9 return data; 10 }
11
12 public object Test2(ISubscribe s, object d) 13 {
14 return d; 15 }
16
17 public object Test3(ISubscribe s, object d) 18 {
19 return d; 20 }
21
22 public object Test4(ISubscribe s, object d) 23 {
24 return d; 25 }
26
27 public object Test5(ISubscribe s, object d) 28 {
29 return s.SubscribeName; 30 }
31
32 //测试删除订阅
33 [TestMethod]
34 public void TestRemoveSubscribe() 35 {
36 PubSubCenter pbc = new PubSubCenter(); 37 pbc.AddSubscribe(“t1”, Test5, “1”);
38 pbc.AddSubscribe(“t1”, Test5, “2”);
39 pbc.RemoveSubscribe(“t1”, “2”);
40 List<string> al = new List<string>();
41 foreach (string item in pbc.Publish(“t1”))
42 {
43 al.Add(item);
44 }
45 Assert.IsTrue(al.Count == 1);
46 Assert.IsTrue(al[0] == “1”);
47 pbc.AddSubscribe(“t1”, Test5, “2”);
48 pbc.RemoveSubscribe(“t1”, “1”);
49 al.Clear();
50 foreach (string item in pbc.Publish(“t1”))
51 {
52 al.Add(item);
53 }
54 Assert.IsTrue(al.Count == 1);
55 Assert.IsTrue(al[0] == “2”);
56 }
57
58 //测试重载版本的订阅发布
59 [TestMethod]
60 public void TestMoreSubscribeAndPublish() 61 {
62 PubSubCenter pbc = new PubSubCenter(); 63 Subscribe subscribe = new Subscribe(“t1”, Test2, “2”, “1”);
64 Subscribe subscribe2 = new Subscribe(“t1”, Test2, “2”);
65 Subscribe subscribe3 = new Subscribe(); 66 subscribe3.SubscribeMethod = Test2; 67 subscribe3.SubscribeName = “3”;
68 subscribe3.SubscribeTag = “t1”;
69 pbc.AddSubscribe(subscribe);
70 pbc.AddSubscribe(subscribe2);
71 pbc.AddSubscribe(subscribe3);
72 pbc.AddSubscribe(“t1”, Test2, “4”);
73 pbc.AddSubscribe(“t1”, Test2, “2”, “5”);
74 List<object> al = new List<object>();
75 foreach (object item in pbc.Publish(“t1”))
76 {
77 al.Add(item);
78 }
79 Assert.IsTrue(al.Count == 5);
80 Assert.IsNotNull(al[0]);
81 Assert.IsNotNull(al[1]);
82 Assert.IsNotNull(al[2]);
83 Assert.IsNotNull(al[3]);
84 Assert.IsNotNull(al[4]);
85 al.Clear();
86 foreach (object item in pbc.Publish(“t1”,”2”))
87 {
88 al.Add(item);
89 }
90 Assert.IsTrue(al.Count == 5);
91 Assert.IsNotNull(al[0]);
92 Assert.IsNotNull(al[1]);
93 Assert.IsNotNull(al[2]);
94 Assert.IsNotNull(al[3]);
95 Assert.IsNotNull(al[4]);
96
97 Publish pub = new Publish(“t1”);
98 al.Clear();
99 foreach (object item in pbc.Publish(pub)) 100 { 101 al.Add(item); 102 } 103 Assert.IsTrue(al.Count == 5); 104 Assert.IsNotNull(al[0]); 105 Assert.IsNotNull(al[1]); 106 Assert.IsNotNull(al[2]); 107 Assert.IsNotNull(al[3]); 108 Assert.IsNotNull(al[4]); 109
110 pub = new Publish(“t1”, “2”); 111 al.Clear(); 112 foreach (object item in pbc.Publish(pub)) 113 { 114 al.Add(item); 115 } 116 Assert.IsTrue(al.Count == 5); 117 Assert.IsNotNull(al[0]); 118 Assert.IsNotNull(al[1]); 119 Assert.IsNotNull(al[2]); 120 Assert.IsNotNull(al[3]); 121 Assert.IsNotNull(al[4]); 122
123 pub = new Publish(); 124 pub.PublishData = “2”; 125 pub.PublishTag = “t1”; 126 al.Clear(); 127 foreach (object item in pbc.Publish(pub)) 128 { 129 al.Add(item); 130 } 131 Assert.IsTrue(al.Count == 5); 132 Assert.IsNotNull(al[0]); 133 Assert.IsNotNull(al[1]); 134 Assert.IsNotNull(al[2]); 135 Assert.IsNotNull(al[3]); 136 Assert.IsNotNull(al[4]); 137 } 138
139 //测试重名订阅事件
140 [TestMethod] 141 public void TestSameNameSubscribe() 142 { 143 PubSubCenter pbc = new PubSubCenter(); 144 pbc.AddSubscribe(“t1”, Test2, “2”); 145 pbc.AddSubscribe(“t1”, Test2, “2”); 146 pbc.AddSubscribe(“t1”, Test2, “3”); 147 List<string> al = new List<string>(); 148 foreach (string item in pbc.Publish(“t1”, “123”)) 149 { 150 al.Add(item); 151 } 152 Assert.IsTrue(al.Count == 2); 153 Assert.IsTrue(al[0] == “123”); 154 Assert.IsTrue(al[1] == “123”); 155 } 156
157 //测试多方法订阅单事件
158 [TestMethod] 159 public void TestMoreSubscribeToOnePublish() 160 { 161 PubSubCenter pbc = new PubSubCenter(); 162 pbc.AddSubscribe(“t1”, Test2, “1”); 163 pbc.AddSubscribe(“t1”, Test3, “2”); 164 pbc.AddSubscribe(“t1”, Test4, “3”); 165 List<string> al = new List<string>(); 166 foreach (string item in pbc.Publish(“t1”, “2”)) 167 { 168 al.Add(item); 169 } 170 Assert.IsTrue(al.Count == 3); 171 Assert.IsTrue(al[0] == “2”); 172 Assert.IsTrue(al[1] == “2”); 173 Assert.IsTrue(al[2] == “2”); 174 } 175
176 //测试单方法订阅多事件
177 [TestMethod] 178 public void TestOneSubscribeToMorePublish() 179 { 180 PubSubCenter pbc = new PubSubCenter(); 181 pbc.AddSubscribe(“t1”, Test1, “2”, “t1”); 182 pbc.AddSubscribe(“t2”, Test1, “3”, “t2”); 183 pbc.AddSubscribe(“t3”, Test1, “4”, “t3”); 184 pbc.AddSubscribe(“t4”, Test1, “5”, “t4”); 185 IList al = new List(); 186 foreach(String item in pbc.Publish(“t1”,”2”)) 187 { 188 al.Add(item); 189 } 190 Assert.IsTrue(al.Count == 1); 191 Assert.IsTrue(al[0] == “2”); 192 al.Clear(); 193 foreach (String item in pbc.Publish(“t2”, “3”)) 194 { 195 al.Add(item); 196 } 197 Assert.IsTrue(al.Count == 1); 198 Assert.IsTrue(al[0] == “3”); 199 al.Clear(); 200 foreach (String item in pbc.Publish(“t3”, “4”)) 201 { 202 al.Add(item); 203 } 204 Assert.IsTrue(al.Count == 1); 205 Assert.IsTrue(al[0] == “4”); 206 al.Clear(); 207 foreach (String item in pbc.Publish(“t4”, “5”)) 208 { 209 al.Add(item); 210 } 211 Assert.IsTrue(al.Count == 1); 212 Assert.IsTrue(al[0] == “5”); 213 } 214 } 215 }

复制代码