Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to resolve cache service from within ViewComponent

I'm registering the caching service in Startup.cs as follows:

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddMemoryCache();            
        services.AddTransient<DataFacade, DataFacade>();
        ...
    }

In the same project my _Layout.cshtml header contains a ViewComponent

@await Component.InvokeAsync(nameof(ViewComponents.PageHeader))

This makes a call to a ModelBuilder component and has a constructor as follows:

using MyApp.Services;
using MyApp.Website.ModelBuilder;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Website.ViewComponents
{
    [ViewComponent]
    public class Header : ViewComponent
    {
        private readonly HeaderModelBuilder _modelBuilder;

        public Header(HeaderModelBuilder modelBuilder)
        {
            _modelBuilder = modelBuilder;
        }

...and the ModelBuilder service references a DataFacade service:

using MyApp.Data.ExternalCountryData;
using MyApp.Services;
using MyApp.Website.Constants;
using MyApp.Website.Models;

namespace MyApp.Website.ModelBuilder
{
    public class HeaderModelBuilder
    {
        private readonly DataFacade _dataFacade;

        public HeaderModelBuilder(DataFacade dataFacade)
        {
            _dataFacade = dataFacade;
        }

...which has a constructor as follows:

using System;
using MyApp.Data;
using MyApp.Data.ExternalSiteData;
using MyApp.Domain.Services.Data;
using Microsoft.Extensions.Caching.Memory;

namespace MyApp.Services
{
    public class DataFacade
    {
        private MemoryCache _cache;
        public DataFacade(MemoryCache memoryCache)
        {
            _cache = memoryCache;
        }

However, when running the code I get the following thrown by Program.cs:

InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Caching.Memory.MemoryCache' while attempting to activate 'MyApp.Services.DataFacade'.

If I comment out the view component, the cache can be accessed fine by other parts of the app.

Why would the view component be having problems? Am I registering one of the services wrongly?

like image 253
CompanyDroneFromSector7G Avatar asked Nov 25 '25 13:11

CompanyDroneFromSector7G


1 Answers

Inject the IMemoryCache abstraction and not the implementation

public class DataFacade {
    private readonly IMemoryCache _cache;

    public DataFacade(IMemoryCache memoryCache) {
        _cache = memoryCache;
    }

    //...

Reference Use IMemoryCache

The source code that adds memory cache adds the interface when registering with the service collection

/// <summary>
/// Adds a non distributed in memory implementation of <see cref="IMemoryCache"/> to the
/// <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddMemoryCache(this IServiceCollection services)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    services.AddOptions();
    services.TryAdd(ServiceDescriptor.Singleton<IMemoryCache, MemoryCache>());

    return services;
}

Source

like image 178
Nkosi Avatar answered Nov 27 '25 03:11

Nkosi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!