Я использую IMemoryCache в проекте Asp.Net Core 2.1 Webapi для временного хранения некоторых данных, полученных из канала RabbitMq. У меня есть слушатель канала в специализированном промежуточном программном обеспечении. Но когда я пытаюсь получить доступ к данным в кеше с контроллера, в нем нет данных. Я использую Autofac в качестве моей DI-фреймворка.
Если я установлю значение в кэш-память в контроллере, я смогу получить его из других классов, например службы (также зарегистрированной в Autofac DI), связанной с этим контроллером.
Моя реализация выглядит следующим образом:
- В 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);
}
В промежуточном программном обеспечении у меня
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
В контроллере у меня
[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
всегда пуст.
Я установил точку останова в своем промежуточном программном обеспечении и подтвердил, что данные были установлены в кэш.
Я неправильно использую кеш-память? Спасибо