Search code examples
c#dependency-injection.net-coredistributed-caching

IDistributedCache available but the data is no longer in the cache?


I am using the services.AddDistributedMemoryCache() in my .Net Core 3 web api startup.cs class. When I first set the cache:

public void SetCommandEventMappingCache(IServiceCollection serviceCollection)
{
    var cache = serviceCollection.BuildServiceProvider().GetService<IDistributedCache>();

    var mappingList = new List<CommandEventMapping>()
    {
        new CommandEventMapping()
        {
            ActionType = "add",
            GrowFlowCommand = new AddEmployee(),
            GrowFlowEvent = "EmployeeAdded",
            TraceabilityCommand = "employee_add"
        }
    };

    cache.Set<List<CommandEventMapping>>(
        "command_event_mappings", mappingList,new DistributedCacheEntryOptions()
    {
        AbsoluteExpiration = DateTimeOffset.Now.AddDays(1)
    });

    //I am able to get back the command_event_mappings here.
    //Once the IDistributedCache is injected. the data is lost
    var commandMapping = cache.Get<List<CommandEventMapping>>("command_event_mappings");
}

In all the examples I have seen, this is typically how it is setup. The only difference is I added a couple extension for Set<T> and Get<T>. I did try it without the new extension methods and had the same result. The actual IDistributedCache when it is injected is available, but the data previously cached is gone. Here is an example of how I inject it.

public LegacyCommandBus(IServiceProvider provider, IDistributedCache cache,
    ITraceabilityTenantService tenantService, IHttpClientFactory httpClientFactory)
    : base(provider)
{
    _provider = provider;
    _cache = cache;
    _tenantService = tenantService;
    _httpClientFactory = httpClientFactory; 
    //This is null
    _commandEventMappings = cache.Get<List<CommandEventMapping>>("command_event_mappings");
}

Solution

  • var cache = serviceCollection.BuildServiceProvider().GetService<IDistributedCache>();
    

    Every time you call BuildServiceProvider(), you are generating a new container with it's own set of singletons (different from the ones injected using the built in DI).

    The solution is to resolve your instance of IDistributedCache inside the Configure in your Startup class.

    public void Configure(IApplicationBuilder app, IDistributedCache cache) { 
        //...
    }