You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型IPublisherService依赖注入报错:无法找到合适构造函数

泛型依赖注入失败问题解决

问题场景

使用未绑定泛型进行依赖注入时,注入服务失败,相关代码及错误信息如下:

接口定义

public interface IPublisherService<TEntity> where TEntity : class
{
    Task<TEntity> PublishAsync(TEntity entity, CancellationToken cancellationToken);
}

服务实现

public class PublisherService<TEntity> : IPublisherService<TEntity> where TEntity : class
{
    private readonly ILogger _logger;
    private readonly IPublishEndpoint _publishEndpoint;

    protected PublisherService(ILogger<PublisherService<TEntity>> logger, IPublishEndpoint publishEndpoint)
    {
        this._logger = logger ?? throw new ArgumentNullException(nameof(logger));
        this._publishEndpoint = publishEndpoint ?? throw new ArgumentNullException(nameof(publishEndpoint));
    }
    
    public async Task<TEntity> PublishAsync(TEntity entity, CancellationToken cancellationToken)
    {
        try
        {
            await _publishEndpoint.Publish(entity, cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogInformation($"Could not send message to queue Reason: {ex.Message}");
        }
        return entity;
    }
}

服务注册

public static class ServiceCollectionExtension
{
    public static IServiceCollection RegisterPublishers(this IServiceCollection services) => services
        .AddScoped(typeof(IPublisherService<>), typeof(PublisherService<>));
}

// 注册调用
builder.Services.RegisterPublishers();

错误提示

System.InvalidOperationException: A suitable constructor for type 'Marel.Livestock.MassTransit.Publisher.Services.Generics.PublisherService`1[Marel.Livestock.Models.TestClass.TheTestClass]' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.

错误调用栈:

at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateOpenGeneric(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot, Boolean throwOnConstraintViolation)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateOpenGeneric(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
   at lambda_method10(Closure , IServiceProvider , Object[] )
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()

问题原因

.NET依赖注入容器仅能访问类的public构造函数来实例化对象,当前PublisherService<TEntity>的构造函数使用protected修饰,容器无法调用该构造函数创建服务实例,因此抛出无法找到合适构造函数的错误。

解决步骤

将PublisherService<TEntity>的构造函数访问修饰符改为public即可:

public class PublisherService<TEntity> : IPublisherService<TEntity> where TEntity : class
{
    private readonly ILogger _logger;
    private readonly IPublishEndpoint _publishEndpoint;

    // 修改为public构造函数
    public PublisherService(ILogger<PublisherService<TEntity>> logger, IPublishEndpoint publishEndpoint)
    {
        this._logger = logger ?? throw new ArgumentNullException(nameof(logger));
        this._publishEndpoint = publishEndpoint ?? throw new ArgumentNullException(nameof(publishEndpoint));
    }
    
    // 其余代码保持不变
}

额外说明

若需保留构造函数的protected修饰(例如用于子类继承),可通过以下方式处理:

  • 为子类添加public构造函数
  • 使用工厂模式手动创建服务实例并注册到DI容器中

但对于当前场景,直接将构造函数改为public是最简单有效的解决方案。

内容的提问来源于stack exchange,提问作者CorrieJanse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 04:07:01