Skip to content

6.Autofac EventBus

nainaigu edited this page May 2, 2020 · 1 revision

Autofac打标签模式 轻松实现EventBus【Event aggregator and messenger】

使用场景

  • 打个标签自动注册成为事件监听者
  • 支持事件处理者(无参数返回)
  • 支持事件处理者(有参数返回)
  • 支持同步和异步事件

比如订单支付成功触发事件给以下事件接收者 : 发送给客人短信,发送运营钉钉通知,调用供应商api下单等

事件发送者

本插件自带实现了一个EventBus,可以在需要EventBus的场景下使用

    [Component]
    public class WorkPublisher
    {
        // 事件发送者可以注入进来
        [Autowired]
        public IEventPublisher EventPublisher { get; set; }
    }
    

或者

    [Component]
    public class WorkPublisher
    {
        // 异步的事件发送者可以注入进来
        [Autowired]
        public IAsyncEventPublisher AsyncEventPublisher { get; set; }
    }
    
同步事件发布器【IEventPublisher】 说明
Publish方法 同步的事件发送者
Publish《T》 同步的事件发送者并拿到返回值[T为返回值类型]
异步事件发布器【IAsyncEventPublisher】 说明
PublishAsync方法 异步的事件发送者
PublishAsync《T》 异步的事件发送者并拿到返回值[T为返回值类型]

事件订阅者

订阅类型 说明 使用方法
IHandleEvent《T1》 同步的事件订阅者 T1是消息类型 Handle 方法 无返回值
IHandleEventAsync《T1》 异步的事件订阅者T1是消息类型 HandleAsync 方法 无返回值
IReturnEvent《T1,T2》 同步的事件处理并得到返回值订阅者T1是消息类型,T2是返回类型 Handle 方法 有返回值
IReturnEventAsync《T1,T2》 异步的事件并得到返回值订阅者T1是消息类型,T2是返回类型 HandleAsync 方法 有返回值

注意有返回值得消息订阅的返回是一个列表,有几个「需要返回值订阅者」就有几个返回值

代码示例:

    //同步事件处理器1
    [Component]
    public class WorkListener1:IHandleEvent<WorkModel1>
    {
        ////也可以注入DI容器的其他类型
        [Autowired]
        public School School { get; set; }
        
        //事件接收
        public void Handle(WorkModel1 @event)
        {
            Console.WriteLine(@event.Name + School.Name);
        }
    }
    
    //同步事件处理器2
    [Component]
    public class WorkListener2:IHandleEvent<WorkModel1>
    {
        //也可以注入DI容器的其他类型
        [Autowired]
        public School School { get; set; }
        
        //事件接收
        public void Handle(WorkModel1 @event)
        {
            
            Console.WriteLine(@event.Name + School.Name);
        }
    }
   
    //异步事件处理器
    [Component]
    public class AsyncWorkListener2:IHandleEventAsync<WorkModel1>
    {
        [Autowired]
        public School School { get; set; }
        public async Task HandleAsync(WorkModel1 @event)
        {
            Console.WriteLine(@event.Name + School.Name);
            await Task.Delay(1000);
        }
    }
    
    
    //同步事件处理器有返回值
    [Component]
    public class WorkReturnListener2:IReturnEvent<WorkModel1,WorkReturnListener2Model>
    {
        [Autowired]
        public School School { get; set; }
        public WorkReturnListener2Model Handle(WorkModel1 @event)
        {
            return new WorkReturnListener2Model
            {
                Name = @event.Name + School.Name
            };
        }
    }
    
    
    //异步事件处理器有返回值
    [Component]
    public class AsyncWorkReturnListener2:IReturnEventAsync<WorkModel1,WorkReturnListener2Model>
    {
        [Autowired]
        public School School { get; set; }

        public async Task<WorkReturnListener2Model> HandleAsync(WorkModel1 @event)
        {
            return await Task.FromResult(new WorkReturnListener2Model
            {
                Name = @event.Name + School.Name
            });
        }
    }
    
    [Component]
    public class WorkPublisher
    {
        //同步事件发送器
        [Autowired]
        public IEventPublisher EventPublisher { get; set; }
        
        //异步事件发送器
        [Autowired]
        public IAsyncEventPublisher AsyncEventPublisher { get; set; }
    }    

事件发送和订阅测试代码:

        var builder = new ContainerBuilder();

        // autofac打标签模式
        builder.RegisterModule(new AutofacAnnotationModule(typeof(WorkPublisher).Assembly));

        var ioc = builder.Build();

        var a1 = ioc.Resolve<WorkPublisher>();

        Assert.NotNull(a1);
        
        //下面的Publish方法调用会触发 上面的 WorkListener1 和  WorkListener2 的 Hangdle方法
        a1.EventPublisher.Publish(new WorkModel1());

        //下面的方法会触发上面的 WorkListener1 和  WorkListener2 的 Hangdle方法 并且 触发上面的  WorkReturnListener2 的 Handle 方法并拿到返回值
        List<WorkReturnListener2Model> sendResult = a1.EventPublisher.Publish<WorkReturnListener2Model>(new WorkModel1());

        //下面的方法会触发上面的 AsyncWorkListener2 的HandleAsync方法
        await a1.AsyncEventPublisher.PublishAsync(new WorkModel1());
        
        //下面的方法会触发上面的 AsyncWorkListener2 的HandleAsync方法 并且触发上面的 AsyncWorkReturnListener2 的 HandleAsync方法并拿到返回值
        List<WorkReturnListener2Model> sendAsyncResult = await a1.AsyncEventPublisher.PublishAsync<WorkReturnListener2Model>(new WorkModel1());