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<IPushNotificationRepository, PushNotificationRepository>();
更改为services.AddScoped<IPushNotificationRepository, PushNotificationRepository>();
【参考方案1】:
单例不能引用 Scoped 实例。错误信息很清楚。
无法使用范围服务 来自单例的“Services.Messaging.Data.PushNotificationsContext”
PushNotificationsContext 被视为范围服务。您几乎不应该从单例中使用范围服务或瞬态服务。您还应该避免使用作用域服务中的瞬态服务。使用作用域服务,注入你需要的东西是一个很好的做法,它会在请求后自动清理。
要么
services.AddTransient ();
或
services.AddScoped
();
可以正常工作,但请检查您的设计。也许这不是您要寻找的行为。
【讨论】:
感谢您的回答和解释。我不知道 DbContext 总是会作为范围注入。这解决了问题,因为我在控制器请求生命周期内完成了所有必需的工作。【参考方案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 欢迎您。如果您已经解决了问题,您可以接受答案吗?如果您有任何其他问题,您可以发布一个新的帖子。以上是关于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当中应用)