回到目录
之前在. netFramework 平台用的好好的,可升级到. net core 平台之后,由于不再需要二进制序列化,导致咱们的事件机制遇到了问题,之前大叔的事件一直是将处理程序序列化后进行存储的,处理存储的参数为事件源,一个事件源可以由多个处理程序订阅,当事件源被发布时,这些被序列化的代码段会被回调执行,这是大叔之前的思路,在 RedisBus 和 MemoryBus 里已经得到了实现,读过大叔源代码的同学应该有所了解了。
- /// <summary>
- /// 事件源
- /// </summary>
- public class CreateUserCommand: BusData {
- public string UserName {
- get;
- set;
- }
- }
- /// <summary>
- /// 事件处理程序
- /// </summary>
- public class CreateUserCommandHandler: IBusHandler {
- public void Handle(CreateUserCommand evt) {
- LoggerFactory.CreateLog().Logger_Debug(evt.UserName);
- Console.WriteLine("CreateUserCommandHandler");
- }
- }
数据变更的定义
- /// <summary>
- /// redis key
- /// </summary>
- const string ESBKEY = "IoCESBBus";
- /// <summary>
- /// redis事件字典
- /// </summary>
- IDatabase redis = RedisManager.Instance.GetDatabase();
- /// <summary>
- /// 模式锁
- /// </summary>
- private static object _objLock = new object();
- /// <summary>
- /// 对于事件数据的存储,目前采用内存字典
- /// </summary>
- private readonly IContainer container = new AutofacContainer();
事件的统一订阅
- public void SubscribeAll() {
- var types = AssemblyHelper.GetTypesByInterfaces(typeof(IBusHandler < >));
- Dictionary < string,
- List < string >> keyDic = new Dictionary < string,
- List < string >> ();
- foreach(var item in types) {
- if (!item.IsGenericParameter) {
- TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(item);
- foreach(var t in typeInfo.GetMethods().Where(i = >i.Name == "Handle")) {
- //ioc name key
- var eventKey = t.GetParameters().First().ParameterType.Name;
- var key = t.GetParameters().First().ParameterType.Name + "_" + item.Name;
- //eventhandler
- var inter = typeof(IBusHandler < >).MakeGenericType(t.GetParameters().First().ParameterType);
- container.Register(inter, item, key);
- if (keyDic.ContainsKey(eventKey)) {
- var oldEvent = keyDic[eventKey];
- oldEvent.Add(key);
- } else {
- var newEvent = new List < string > ();
- newEvent.Add(key);
- keyDic.Add(eventKey, newEvent);
- }
- }
- }
- //redis存储事件与处理程序的映射关系
- foreach(var hash in keyDic) redis.HashSet(ESBKEY, hash.Key.ToString(), JsonConvert.SerializeObject(hash.Value));
- }
- }
事件的发布,相关处理程序会从容器中取出,并执行它们的 Handler 方法
- public void Publish(TEvent@event) where TEvent: class,
- IBusData {
- var keyArr = JsonConvert.DeserializeObjectstring >> (redis.HashGet(ESBKEY, typeof(TEvent).Name));
- foreach(var key in keyArr) {
- var item = container.ResolveNamed > (key);
- item.Handle(@event);
- }
- }
说到这里,大叔的服务总线的 IoC 实现方式就算是完成了,经过测试后,在. net core 上表现也很不错!
自己也骄傲一次,呵呵!
回到目录
来源: http://www.cnblogs.com/lori/p/7158071.html