【问题标题】:Unable to resolve cache service from within ViewComponent无法从 ViewComponent 中解析缓存服务
【发布时间】:2020-02-10 23:30:08
【问题描述】:

我在 Startup.cs 中注册缓存服务如下:

    public void ConfigureServices(IServiceCollection services)
    {

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

在同一个项目中,我的 _Layout.cshtml 标头包含一个 ViewComponent

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

这会调用 ModelBuilder 组件并具有如下构造函数:

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;
        }

...并且 ModelBuilder 服务引用了 DataFacade 服务:

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;
        }

...它的构造函数如下:

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;
        }

但是,在运行代码时,Program.cs 会抛出以下内容:

InvalidOperationException:无法解析服务类型 'Microsoft.Extensions.Caching.Memory.MemoryCache' 尝试 激活“MyApp.Services.DataFacade”。

如果我注释掉视图组件,应用程序的其他部分可以正常访问缓存。

为什么视图组件会出现问题?我是否错误地注册了其中一项服务?

【问题讨论】:

    标签: c# dependency-injection .net-core razor-pages memorycache


    【解决方案1】:

    注入IMemoryCache 抽象而不是实现

    public class DataFacade {
        private readonly IMemoryCache _cache;
    
        public DataFacade(IMemoryCache memoryCache) {
            _cache = memoryCache;
        }
    
        //...
    

    参考Use IMemoryCache

    添加内存缓存的源码在向服务集合注册时添加接口

    /// <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

    【讨论】:

      猜你喜欢
      • 2017-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-11
      • 2019-06-29
      • 1970-01-01
      相关资源
      最近更新 更多