ASP.NET Core Web应用程序DI错误 - 一些服务无法构建(验证服务描述符时出错)

5

我正在创建一个ASP.NET Core Web应用程序。我通过一个库项目使用Repository。我在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);
}

在仓库中,我注入了db上下文。

    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: “某些服务无法构建(Error while validating the service descriptor 'ServiceType: Services.Messaging.Data.Abstract.IPushNotificationRepository Lifetime: Singleton ImplementationType: Services.Messaging.Data.PushNotificationRepository': Cannot consume scoped service 'Services.Messaging.Data.PushNotificationsContext' from singleton 'Services.Messaging.Data.Abstract.IPushNotificationRepository'.)”。

真的很希望能得到一些关于此问题的建议。


services.AddSingleton<IPushNotificationRepository, PushNotificationRepository>(); 更改为 services.AddScoped<IPushNotificationRepository, PushNotificationRepository>(); - Vidmantas Blazevicius
2个回答

10

一个单例不能引用作用域实例。错误信息很清楚。

无法从单例消耗作用域服务'Services.Messaging.Data.PushNotificationsContext'。

PushNotificationsContext被视为作用域服务。你几乎不应该从单例消耗作用域服务或瞬态服务。你也应该避免从作用域服务中消耗瞬态服务。消耗作用域服务是一种良好的实践,注入需要的内容后会自动清理请求。

要么

services.AddTransient < IPushNotificationRepository, PushNotificationRepository>();

要么

services.AddScoped< IPushNotificationRepository, PushNotificationRepository>();

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


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

2

services.AddDbContext<PushNotificationsContext>() 注册了 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
@sm101 您好,欢迎您。如果您已经解决了问题,能否接受答案呢?如果您有其他问题,可以发起一个新的讨论线程。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接