Asp.net core利用MediatR进程内发布/订阅详解

编程学习 2021-07-04 22:41www.dzhlxh.cn编程入门
这篇文章主要给大家介绍了关于Asp.net core利用MediatR进程内发布/订阅的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Asp.net core具有一定的参考学习价值,需要的朋友们狼蚁网站SEO优化来一起学习学习吧

1、背景

最近,一个工作了一个月的同事离职了,所做的东西怼了过来。一看代码,惨不忍睹,一个方法六七百行,啥也不说了吧,实在没法儿说。介绍下业务场景吧,一个公共操作A,业务中各个地方都会做A操作,正常人正常思维应该是把A操作提取出来封装,其他地方调用,可这哥们儿偏偏不这么干,代码到处复制。仔细分析了整个业务之后,发现是一个典型的事件/消息驱动型,或者叫发布/订阅型的业务逻辑。鉴于系统是单体的,所以想到利用进程内发布/订阅的解决方案。记得很久之前,做WPF时候,用过Prism的EventAggregator(是不是暴露年龄了。。。),那玩意儿不知道现在还在不在,支不支持core,目前流行的是MediatR,跟core的集成也好,于是决定采用MediatR。

2.Demo代码

Startup服务注册:

public void ConfigureServices(IServiceCollection services)
  {
   services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
   services.AddScoped<IService1, Service1>();
   services.AddScoped<IService2, Service2>();
   services.AddScoped<IContext, Context>();
   services.AddMediatR(typeof(SomeEventHandler).Assembly);
  }

服务1:

public class Service1 : IService1
  {
    private readonly ILogger _logger;
    private readonly IMediator _mediator;
    private readonly IContext _context;
    private readonly IService2 _service2;

    public Service1(ILogger<Service1> logger,
      IMediator mediator,
      IContext context)
    {
      _logger = logger;
      _mediator = mediator;
      _context = context;
      //_service2 = service2;
    }

    public async Task Method()
    {
      _context.CurrentUser = "test";
      //await _service2.Method();
      //_service2.Method();
      await _mediator.Publish(new SomeEvent());
      //_mediator.Publish(new SomeEvent());

      await Task.CompletedTask;
    }
  }

可以看到,在服务1的method方法中,发布了SomeEvent事件消息。

服务2代码:

public class Service2 : IService2
  {
    private readonly ILogger _logger;
    private readonly IContext _context;

    public Service2(ILogger<Service2> logger,
      IContext context)
    {
      _logger = logger;
      _context = context;
    }

    public async Task Method()
    {
      _logger.LogDebug("当前用户:{0}", _context.CurrentUser);
      await Task.Delay(5000);
      //_logger.LogDebug("当前用户:{0}", _context.CurrentUser);
      _logger.LogDebug("Service2 Method at :{0}", DateTime.Now);
    }
  }

解释下,为啥服务2 Method方法中,要等待5秒,因为实际项目中,有这么一个操作,把一个压缩程序包传递到远端,然后在远端代码操作IIS创建站点,这玩意儿非常耗时,大概要1分多钟,这里我用5s模拟,意思意思。这个5s至关重要,待会儿会详述。

再看事件订阅Handler:

public class SomeEventHandler : INotificationHandler<SomeEvent>, IDisposable
  {
    private readonly ILogger _logger;
    private readonly IServiceProvider _serviceProvider;
    private readonly IService2 _service2;

    public SomeEventHandler(ILogger<SomeEventHandler> logger,
      IServiceProvider serviceProvider,
      IService2 service2)
    {
      _logger = logger;
      _serviceProvider = serviceProvider;
      _service2 = service2;
    }

    public void Dispose()
    {
      _logger.LogDebug("Handler disposed at :{0}", DateTime.Now);
    }

    public async Task Handle(SomeEvent notification, CancellationToken cancellationToken)
    {
      await _service2.Method();
      //using (var scope = _serviceProvider.CreateScope())
      //{
      //  var service2 = scope.ServiceProvider.GetService<IService2>();
      //  await service2.Method();
      / 

Copyright © 2016-2025 www.dzhlxh.cn 金源码 版权所有 Power by

网站模板下载|网络推广|微博营销|seo优化|视频营销|网络营销|微信营销|网站建设|织梦模板|小程序模板