每次调用方法时,.NET核心中的生存期限

时间:2018-05-10 08:13:15

标签: c# scope rabbitmq .net-core

我有两个通过RabbitMQ进行通信的服务,我想为每个收到的消息应用一个范围生存期。

我的消费者:

 public class Consumer
 {
    private IModel channel;
    public Consumer(IModel channel)
    {
        this.channel = channel;
    }
    public void Consume()
    {
        var queue = channel.QueueDeclare(queue: MessagingConfigs.QueueName,
            durable: false,
            exclusive: false,
            autoDelete: false,
            arguments: null);
        var consumer = new EventingBasicConsumer(channel);
        consumer.Received += (model, args) => HandleMessageReceived(model, args);
        channel.BasicConsume(queue: MessagingConfigs.QueueName, autoAck: false, consumer: consumer);
    }

    private async Task HandleMessageReceived(object model, BasicDeliverEventArgs args)
    {
        //do logic
    }
}

每次触发Received事件时都会调用HandleMessageReceived,每次调用HandleMessageReceived时如何打开新范围?

在线找到解决方案:

public void ConfigureServices(IServiceCollection services)

{
services.AddScoped<IMyScopedService, MyScopedService>();

var serviceProvider = services.BuildServiceProvider();

var serviceScopeFactory = serviceProvider.GetRequiredService<IServiceScopeFactory>();

IMyScopedService scopedOne;

using (var scope = serviceScopeFactory.CreateScope())
{
    scopedOne = scope.ServiceProvider.GetService<Consumer>();
    Consumer.Consume();
}
}

我想如果我在startup.cs中使用上面的内容,那么将在应用程序生命周期中调用一次,并且scope将被打开一次,以下内容可能会有效:

private async Task HandleMessageReceived(object model, BasicDeliverEventArgs args)
    { using (var scope = serviceScopeFactory.CreateScope())
     {
        //do logic
     }
    }

但我不想在我的消费者代码中包含生命周期注册,.Net核心是否有办法在每次调用方法时自动打开一个范围,我可以在startup.cs中使用或者的Program.cs?

我的应用程序是.net核心控制台应用程序而不是ASP.NET

1 个答案:

答案 0 :(得分:1)

为什么不在附件中包装方法?

首先,为方法创建包装器:

public static class ScopeFactoryExtension
{
   public static EventHandler<BasicDeliverEventArgs> WrapInScope(this IServiceScopeFactory scopeFactory, Func<IMyScopedService, object, BasicDeliverEventArgs, Task> func)
   {
      async void InScope(object arg1, BasicDeliverEventArgs arg2)
      {
         using (var scope = scopeFactory.CreateScope())
         {
            await func(scope, arg1, arg2);
         }
      }

      return InScope;
   }
}

然后包装整个方法:

consumer.Received += scopeFactory.WrapInScope(HandleMessageReceived);

还需要扩展方法:

private async Task HandleMessageReceived(IMyScopedService service, object model, BasicDeliverEventArgs args)
{
   //do logic with service
}