ASP.NET Core Web App DI 错误 - 无法构造某些服务(验证服务描述符时出错

Posted

技术标签:

【中文标题】ASP.NET Core Web App DI 错误 - 无法构造某些服务(验证服务描述符时出错【英文标题】:ASP.NET Core Web App DI Error - Some services are not able to be constructed (Error while validating the service descriptor 【发布时间】: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;(); 【参考方案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 欢迎您。如果您已经解决了问题,您可以接受答案吗?如果您有任何其他问题,您可以发布一个新的帖子。

以上是关于ASP.NET Core Web App DI 错误 - 无法构造某些服务(验证服务描述符时出错的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

Ninject 中的 .NET Core DI 范围生命周期

NET Core控制反转(IoC)

ASP.NET Core 依赖注入(DI)