找不到适合类型“RestDataService”的构造函数

may*_*pta 7 .net c# oop .net-core asp.net-core

运行 .Net Core 2.0 API 端点时出现以下错误。

找不到适合类型“RestDataService”的构造函数。确保类型是具体的,并且为公共构造函数的所有参数注册了服务。

 public partial class RestDataService : IRestDataService
    {
        private static HttpClient _client;
        private static AppConfiguration _configuration;
        private const short MaxRetryAttempts = 3;
        private const short TimeSpanToWait = 2;

        public RestDataService(AppConfiguration configuration)
        {
            _client = configuration.HttpClient;
            _configuration = configuration;
        }
........
Run Code Online (Sandbox Code Playgroud)

我的创业班是这样的:

  // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            var config = new AppConfiguration
            {
                Environment = Configuration["environment"],
            };

            services.AddMvc().AddJsonOptions(o => o.SerializerSettings.NullValueHandling = NullValueHandling.Include);
            services.AddMemoryCache();
            services.AddCors();
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
                services.AddSingleton(Configuration);
                services.AddSingleton(config);
            services.AddLogging();
            services.AddTransient<IRestDataService, RestDataService>();

services.AddHttpClient<IRestDataService, RestDataService>()
                .AddPolicyHandler(request => request.Method == HttpMethod.Get ? retryPolicy : noOp);

Run Code Online (Sandbox Code Playgroud)

任何建议,摆脱这个?构造函数已经是公共的并且所有参数都在启动文件中注册

Cry*_*ptc 9

我收到错误消息“找不到适合类型 '<type>' 的构造函数。” 在意外生成受保护的构造函数而不是 公共构造函数之后。将其标记回公共修复它。

  • 奥斯卡奖颁给了……Cryptc (6认同)
  • 非常感谢你做的这些。我有完全相同的问题。我刚刚花了最后 30 分钟删除构造函数参数并显式从提供者那里获取服务。这篇文章解决了我的问题。本来应该很明显的,但我没有发现。 (5认同)
  • 另外,确保控制器构造函数是公共的,而不是内部的 (3认同)
  • 谢谢你,我花了一个小时试图弄清楚发生了什么事......这么一个小细节,你帮了我很多! (3认同)
  • @Guy_g23它应该保持私有,并具有公共实例属性,例如:`public static Singleton Instance { get { return _instance; } }` -- 我推荐:[singleton](https://csharpindepth.com/articles/singleton) (2认同)
  • 是的,这一点我也忽略了。 (2认同)
  • 总是那些愚蠢的事情让你发疯。非常感谢。 (2认同)

Tao*_*hou 6

对于AddHttpClient,您需要为 提供HttpClient参数RestDataService。而且,您需要注册AppConfiguration.

  1. RestDataService

    public class RestDataService: IRestDataService
    {
        private static HttpClient _client;
        private static AppConfiguration _configuration;
        private const short MaxRetryAttempts = 3;
        private const short TimeSpanToWait = 2;
    
        public RestDataService(AppConfiguration configuration
            , HttpClient client)
        {
            _client = configuration.HttpClient;
            _configuration = configuration;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. Startup.cs

    var config = new AppConfiguration
    {
        Environment = Configuration["environment"],
    };
    
    services.AddSingleton(typeof(AppConfiguration), config);
    services.AddHttpClient<IRestDataService, RestDataService>();
    
    Run Code Online (Sandbox Code Playgroud)

  • 我通过从 IHttpClientFactory.GetClient() 获取 HttpClient 来修复它 (2认同)
  • 它可以将 HttpClient 添加为参数,但感觉错误的是您实际上并未使用它。 (2认同)

joh*_*rom 6

我刚刚遇到这个问题,因为我不小心注册HttpClient到了interface.

public void ConfigureServices(IServiceCollection services) {
  // !! Wrong, this is done automatically by AddHttpClient<IMyService, MyService>()
  services.AddTransient<IMyService, MyService>();

  // !! There is no suitable constructor for IMyService, since it is an interface.
  services.AddHttpClient<IMyService>();

  // Instead, let AddHttpClient manage your service's lifetime, 
  // and tell it the implementation.
  // It is registered with a Transient lifetime as described below.
  services.AddHttpClient<IMyService, MyService>();
}
Run Code Online (Sandbox Code Playgroud)

重要上下文,来源: https: //www.stevejgordon.co.uk/ihttpclientfactory-patterns-using-typed-clients-from-singleton-services

在ConfigureServices 方法中定义类型化客户端时,类型化服务将在瞬态范围内注册。这意味着每次需要一个实例时,DI 容器都会创建一个新实例。发生这种情况的原因是 HttpClient 实例被注入到类型化客户端实例中。该 HttpClient 实例的寿命是短暂的,以便 HttpClientFactory 可以确保底层处理程序(和连接)被释放和回收。


pri*_*sar 4

您必须定义要用于 IRestDataService 的具体接口类。所以,这样定义。

services.AddTransient<IRestDataService, RestDataService>();
Run Code Online (Sandbox Code Playgroud)

删除 AppConfiguration 之前的 static 关键字。

private readonly AppConfiguration _configuration;
Run Code Online (Sandbox Code Playgroud)