ASP.NET Core 2.1 - кэш памяти - значение, установленное в промежуточном программном обеспечении, не доступно для контроллера - PullRequest
0 голосов
/ 17 ноября 2018

Я использую IMemoryCache в проекте Asp.Net Core 2.1 Webapi для временного хранения некоторых данных, полученных из канала RabbitMq. У меня есть слушатель канала в специализированном промежуточном программном обеспечении. Но когда я пытаюсь получить доступ к данным в кеше с контроллера, в нем нет данных. Я использую Autofac в качестве моей DI-фреймворка.

Если я установлю значение в кэш-память в контроллере, я смогу получить его из других классов, например службы (также зарегистрированной в Autofac DI), связанной с этим контроллером.

Моя реализация выглядит следующим образом:

  1. В Startup.cs у меня есть

services.AddMemoryCache();

, а затем использовать промежуточное программное обеспечение как

app.UseMiddleware<RabbitMqConsumerMiddleware>();
app.UseCors("default")
    .UseAuthentication()
    .UseMvc();`

Моя регистрация в Autofac выглядит следующим образом:

Вот моя регистрация в Autofac

public IServiceProvider ConfigureServices(IServiceCollection services)
{
RabbitMqConfiguration rabbitMqConfiguration = new RabbitMqConfiguration();
        Configuration.GetSection("RabbitMq").Bind(rabbitMqConfiguration);
        services.AddSingleton(rabbitMqConfiguration);

        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
            .AddDataAnnotationsLocalization()
            .AddControllersAsServices()
            .AddApiExplorer();

        services.AddRabbitMq(rabbitMqConfiguration);
        services.AddMemoryCache();


        ContainerBuilder builder = new ContainerBuilder();

        builder.Populate(services);
        IContainer container = builder.Build();
        return new AutofacServiceProvider(container);
    }
  1. В промежуточном программном обеспечении у меня

    public RabbitMqConsumerMiddleware(RequestDelegate next, IMemoryCache memoryCache, RabbitMqConfiguration configuration, IModel messageBodyReceiverChannel)
    {
        _next = next;
        _memoryCache = memoryCache;
        _configuration = configuration;
        _messageBodyReceiverChannel = messageBodyReceiverChannel;
    }
    
    public async Task Invoke(HttpContext context)
    {
        bool isMessageBodyReceiverConsumerExist = _memoryCache.TryGetValue("message-body-receiver-consumer", out EventingBasicConsumer messageBodyReceiverConsumer);
    
        if (!isMessageBodyReceiverConsumerExist)
        {
            var messageBodyReceiverConsumer = new EventingBasicConsumer(_messageBodyReceiverChannel);
            messageBodyReceiverConsumer.Received += (ch, ea) =>
            {
                MessageBody messageBody = JsonConvert.DeserializeObject<MessageBody>(Encoding.Default.GetString(ea.Body));
    
                if (_memoryCache.TryGetValue("Message Body", out List<MessageBody> cacheMessageBodies))
                {
                    cacheMessageBodies.Add(messageBody);
                }
                else
                {
                    _memoryCache.Set("Message Body",
                        new List<MessageBody> { messageBody });
                }
            };
            _memoryCache.Set("message-body-receiver-consumer", messageBodyReceiverConsumer);
        }
    
        _messageBodyReceiverChannel.BasicConsume(_configuration.MessageReceiverQueue, false, messageBodyReceiverConsumer);
    
        await _next(context);
    }
    

, где messageBody взято из RabbitMq

  1. В контроллере у меня

    [Authorize]
    [Route("[controller]")]
    [ApiController]
    public class MessageBodyController : ControllerBase
    {
    private readonly IApplicationService<Dto.MessageBody> _messageBodyPresenter;
    private readonly IMemoryCache _memoryCache;
    
    public MessageBodyController(IApplicationService<Dto.MessageBody> messageBodyPresenter, IMemoryCache memoryCache)
    {
        _messageBodyPresenter = messageBodyPresenter;
        _memoryCache = memoryCache;
    }
    
    [HttpGet]
    [Route("Stop")]
    public IActionResult Stop()
    {
        ((MessageBodyPresenter)_messageBodyPresenter).Stop();
        return Ok();
    }
    }
    

Но _memoryCache всегда пуст.

Я установил точку останова в своем промежуточном программном обеспечении и подтвердил, что данные были установлены в кэш.

Я неправильно использую кеш-память? Спасибо

1 Ответ

0 голосов
/ 17 ноября 2018

Не зная вашей полной конфигурации, я думаю, что одной из проблем может быть то, что вы зарегистрировали новое промежуточное ПО после промежуточного ПО Mvc.
Ваша регистрация должна выглядеть следующим образом:

app.UseMiddleware<RabbitMqConsumerMiddleware>();
app.UseMvc();
...