标签:oid elar dev 并且 策略 syn reflect system contain
话说EventBroker这玩意已经不是什么新鲜货了,记得第一次接触这玩意是在进第二家公司的时候,公司产品基础架构层中集成了分布式消息中间件,在.net基础服务层中使用EventBroker的模式将消息组装成事件,支持同域、跨域和跨机器进行事件的发布和订阅,后来才知道这玩意叫做EventBroker。不得不承认,这是一个非常聪明的东西,它在内部高度封装了消息和事件的处理,将上层应用的事件和委托的依赖进行解耦,并且提供非常简洁的方式进行开发。OK,本篇文章只是实现了一个简化版本的EventBroker,功能非常有限,也没有集成消息组件,所以也不支持跨域和跨机器的分布式应用了,甚至没有经过严格测试(比如并发处理、跨线程处理等等),社区上更好的实现很多。所以必须声明:只是实验性代码,纯粹练手,带着学习的态度写代码,coding不易,大家不喜勿喷
本篇主要使用.net C#技术,包括委托、反射、弱引用和弱事件模式,写代码也是为了学习这些,找找码感。说明:为了不影响阅读,所贴代码均有一些阉割,如需源码,后续我把附件传上来,不过这源码真没啥东西,我上传就是自己做一个记录,存储下来
思路不用多说,网上搜一下会有很多信息,我比较懒,直接贴一张网上的图可以明确表现出系统的交互场景和交互流程

在应用层使用EventBroker,需要在应用中针对对象进行Register,一般中大型项目使用IOC容器都提供在对象创建时注入特征,比如:
|
1
2
3
4
5
6
|
// 示范代码privatevoidOnObjectBuild(ObjectModel builder, objectinstance){ varbroker = DIContainer.Resolve<IEventBroker>(); broker.Register(instance);} |
这样比较方便,避免在程序中手动Register,不过我这里只是简单实现,不涉及IOC和任何设计的东西,注册对象后,在我们的类中可以像如下的方式实现:
|
1
2
|
publiceventEventHandler<EventModelArgs<string>> MessageArrived; |
以上是事件定义,我们可以把事件委托引用的方法定义在另一个类,而且两者完全不用依赖彼此
|
1
2
3
4
5
|
publicvoidMessageReceived(objectsender, EventModelArgs<string> message){ PrintOut(message.Data);} |
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950namespaceTinyEventBroker{publicclassEventBroker{privatereadonlyEventTopicCollection topics=newEventTopicCollection();/// <summary>/// 事件主题集合列表/// </summary>publicEventTopicCollection Topics{get{returntopics; }}/// <summary>/// 事件场景/// </summary>publicvirtualEventScope EventScope {get{returnEventScope.Local; } }/// <summary>/// 将对象注入到事件总线上/// </summary>publicvoidRegister(objecttarget){BindingFlags bingdings = BindingFlags.Instance | BindingFlags.Static| BindingFlags.Public | BindingFlags.NonPublic;RegisterPublication(target, bingdings);RegisterSubscription(target, bingdings);}/// <summary>/// 注册发布者/// </summary>privatevoidRegisterPublication(objecttarget, BindingFlags bindings){// ……}/// <summary>/// 注册订阅者/// </summary>/// <param name="target"></param>/// <param name="bindings"></param>privatevoidRegisterSubscription(objecttarget, BindingFlags bindings){// ……}}}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586publicclassEventTopic{publicEventTopic() { }publicEventTopic(stringname):this(){this.Name = name;}/// <summary>/// 事件主题标识/// </summary>publicstringName {get;set; }privateList<EventPublication> publishers =newList<EventPublication>();/// <summary>/// 发布者列表/// </summary>internalList<EventPublication> Publishers{get{returnpublishers; }set{ publishers = value; }}privateList<EventSubscription> subscribers =newList<EventSubscription>();/// <summary>/// 订阅者列表/// </summary>internalList<EventSubscription> Subscribers{get{returnsubscribers; }set{ subscribers = value; }}/// <summary>/// 增加发布者/// </summary>internalvoidAddPublication(EventPublication publisher){EventContext.Instance.WriteTo("主题:{0} 添加发布者{1}", Name, publisher);publisher.EventFired += OnEventFired;publishers.Add(publisher);}/// <summary>/// 增加订阅者/// </summary>internalvoidAddSubscription(EventSubscription subscriber){EventContext.Instance.WriteTo("主题:{0} 添加订阅者{1}", Name, subscriber);subscribers.Add(subscriber);}/// <summary>/// 移除发布者/// </summary>internalvoidRemovePublication(EventPublication publisher){EventContext.Instance.WriteTo("主题:{0} 移除发布者{1}", Name, publisher);publishers.Remove(publisher);}/// <summary>/// 移除订阅者/// </summary>internalvoidRemoveSubscription(EventSubscription subscriber){EventContext.Instance.WriteTo("主题:{0} 移除订阅者{1}", Name, subscriber);subscribers.Remove(subscriber);}internalvoidOnEventFired(EventPublication publication,objectsender, EventArgs args){// ......}privatevoidCheckInvalidPublications(){// ......}privatevoidCheckInvalidSubscriptions(){// ......}}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Reflection;usingSystem.Text;usingSystem.Threading.Tasks;namespaceTinyEventBroker{/// <summary>/// 发布者/// </summary>internalclassEventPublication{/// <summary>/// 弱引用对象包装器/// </summary>privatereadonlyWeakReference wrapper;/// <summary>/// 事件名称/// </summary>privatereadonlystringeventName;/// <summary>/// 事件处理委托类型/// </summary>privatereadonlyType eventHandleType;/// <summary>/// 对象名称,用于显示/// </summary>privatereadonlystringtargetName;/// <summary>/// 事件定义,用来桥接对象的Event/// </summary>publiceventTopicEventHandler EventFired;publicEventPublication(objecttarget,stringeventName){wrapper =newWeakReference(target);this.eventName = eventName;this.targetName = target.GetType().Name;EventInfo info = target.GetType().GetEvent(EventName);eventHandleType = info.EventHandlerType;Delegate handler = Delegate.CreateDelegate(EventHandleType,this,this.GetType().GetMethod("OnEventFired"));info.AddEventHandler(target, handler);}/// <summary>/// 获取对象引用/// </summary>publicobjectTarget{get{returnwrapper.Target; }}/// <summary>/// 对象名称,用于显示/// </summary>publicstringTargetName{get{returntargetName; }}/// <summary>/// 判断对象是否存活/// </summary>publicboolIsAlive{get{returnwrapper.IsAlive; }}/// <summary>/// 事件名称/// </summary>publicstringEventName{get{returneventName; }}/// <summary>/// 事件处理类型/// </summary>publicType EventHandleType{get{returneventHandleType; }}publicvirtualvoidOnEventFired(objectsender, EventArgs e){varhandle = EventFired;if(handle !=null)handle(this, sender, e);}publicoverridestringToString(){returnstring.Format("[{0} - {1}]", targetName, eventName);}}}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceTinyEventBroker{/// <summary>/// 订阅者/// </summary>publicclassEventSubscription{/// <summary>/// 弱引用对象包装器/// </summary>privatereadonlyWeakReference wrapper;/// <summary>/// 方法名/// </summary>privatereadonlystringmethodName;/// <summary>/// 对象名称,仅作显示/// </summary>privatereadonlystringtargetName;publicEventSubscription(objecttarget,stringmethodName){this.wrapper =newWeakReference(target);this.methodName = methodName;targetName = target.GetType().Name;}/// <summary>/// 对象是否存活/// </summary>publicboolIsAlive{get{returnwrapper.IsAlive; }}/// <summary>/// 订阅者对象方法名/// </summary>publicstringMethodName {get{returnmethodName; } }/// <summary>/// 订阅者对象,通过弱引用包装访问/// </summary>publicobjectTarget {get{returnwrapper.Target; } }/// <summary>/// 订阅者对象显式名/// </summary>publicstringTargetName {get{returntargetName; } }internalvirtualvoidHandleEvent(EventPublication publication,objectsender, EventArgs args){Delegate handler = Delegate.CreateDelegate(publication.EventHandleType, Target, methodName);handler.DynamicInvoke(sender, args);}publicoverridestringToString(){returnstring.Format("[{0} - {1}]", targetName, methodName);}}}
|
1
|
EventScope,这东西只是保留属性,以后扩展的时候用 |
针对弱引用这个东东,其实直接使用弱事件模式,微软已经封装好了的
Weak Event Patterns,Weak Event in C#
本篇只是EventBroker的简单实现,纯粹就是学习练手,我想,如果后续我有充足的时间,或者工作环境允许,我可以实现得更好,比如可以在内部封装多钟策略,异常处理策略、异步事件策略、处理并发、线程安全的考虑等等。更而甚之,可以将它进行抽象和扩展,加入消息中间件,实现分布式发布者和订阅者,那样就比较有实用价值了。不过写代码水平和效率有限,时间和精力也有限,工作是工作学习是学习,区区一文,聊表我的热情和开发,让代码和生活可以持续下去吧!
标签:oid elar dev 并且 策略 syn reflect system contain
原文地址:https://www.cnblogs.com/chengxuyuanww/p/12004076.html