【问题标题】:ASP.NET Core Web App DI Error - Some services are not able to be constructed (Error while validating the service descriptorASP.NET Core Web App DI 错误 - 无法构造某些服务(验证服务描述符时出错
【发布时间】:2020-06-04 21:58:13
【问题描述】:

我正在创建一个 ASP.NET Core Web 应用程序。我正在通过库项目使用存储库。我在 web 应用项目中引用了它。

仓库界面如下:

public interface IPushNotificationRepository
{
    IQueryable<PushNotification> Notifications
    {
        get;
    }
    IQueryable<Client> Clients
    {
        get;
    }

    void Add(PushNotification notification);
    void Add(Client client);
    void AddRange(IList<PushNotification> notifications);
    bool AddIfNotAlreadySent(PushNotification notification);
    void UpdateDelivery(PushNotification notification);
    bool CheckIfClientExists(string client);
    Client FindClient(int? id);
    void Update(Client client);
    void Delete(Client client);
}

在存储库中我注入数据库上下文

    public class PushNotificationRepository : IPushNotificationRepository
    {
        private readonly PushNotificationsContext _context;

        public PushNotificationRepository(PushNotificationsContext context)
        {
            _context = context;
        }
}

启动类的配置服务如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddSingleton<IPushNotificationRepository, PushNotificationRepository>();
    services.AddDbContextPool<PushNotificationsContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("PushNotificationsConnection")));
}

在控制器类中我使用存储库:

    public class ClientsController : Controller
    {
        //private readonly PushNotificationsContext _context;
        private readonly IPushNotificationRepository _pushNotificationRepository;

        public ClientsController(IPushNotificationRepository pushNotificationRepository)
        {
            _pushNotificationRepository = pushNotificationRepository;
        }
}

存储库类位于 Web 应用程序项目引用的单独库项目中。我收到的错误是:

System.AggregateException: '有些服务不能 构造(验证服务描述符时出错 '服务类型: Services.Messaging.Data.Abstract.IPushNotificationRepository 生命周期: 单例实现类型: Services.Messaging.Data.PushNotificationRepository':无法使用 范围服务“Services.Messaging.Data.PushNotificationsContext”来自 单身人士 'Services.Messaging.Data.Abstract.IPushNotificationRepository'.)'

非常感谢您对此提出建议

【问题讨论】:

  • services.AddSingleton&lt;IPushNotificationRepository, PushNotificationRepository&gt;(); 更改为services.AddScoped&lt;IPushNotificationRepository, PushNotificationRepository&gt;();

标签: c# asp.net-mvc asp.net-core


【解决方案1】:

单例不能引用 Scoped 实例。错误信息很清楚。

无法使用范围服务 来自单例的“Services.Messaging.Data.PushNotificationsContext”

PushNotificationsContext 被视为范围服务。您几乎不应该从单例中使用范围服务或瞬态服务。您还应该避免使用作用域服务中的瞬态服务。使用作用域服务,注入你需要的东西是一个很好的做法,它会在请求后自动清理。

要么

services.AddTransient ();

services.AddScoped();

可以正常工作,但请检查您的设计。也许这不是您要寻找的行为。

【讨论】:

  • 感谢您的回答和解释。我不知道 DbContext 总是会作为范围注入。这解决了问题,因为我在控制器请求生命周期内完成了所有必需的工作。
【解决方案2】:

services.AddDbContext&lt;PushNotificationsContext&gt;()PushNotificationsContext 注册为ServiceLifetime.Scoped 的服务,这意味着您的PushNotificationsContext 是根据Web 请求创建的。请求完成后处理。

您可以将单例的IServiceScopeFactory 注入到您的存储库中,然后使用CreateScope() 创建一个新范围并从该范围请求PushNotificationsContext 服务

public class PushNotificationRepository : IPushNotificationRepository
{
    IServiceScopeFactory _serviceScopeFactory;
    public PushNotificationRepository(IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
    }

    public void Add(PushNotification notification);
    {
        using (var scope = _serviceScopeFactory.CreateScope())
        {
            var context = scope.ServiceProvider.GetRequiredService<PushNotificationsContext>();
            //other logic
        }


    }
}

参考c# - DataContext disposed in ASP.NET Core scheduler

【讨论】:

  • 感谢您的详细解释以及解释长期运行的工作人员实施的链接。对它应该如何实施也有了一个想法。在我的场景中,我正在完成控制器生命周期内的所有任务。再次感谢!
  • @sm101 欢迎您。如果您已经解决了问题,您可以接受答案吗?如果您有任何其他问题,您可以发布一个新的帖子。
猜你喜欢
  • 2023-02-03
  • 2021-07-09
  • 1970-01-01
  • 2021-11-10
  • 2022-06-28
  • 2023-03-08
  • 2021-06-06
  • 1970-01-01
  • 2021-03-14
相关资源
最近更新 更多