C# 使用DI模拟调用.Net核心类库

C# 使用DI模拟调用.Net核心类库,c#,.net-core,dependency-injection,C#,.net Core,Dependency Injection,我在创建控制台程序以调用引用类库中的enrol方法时遇到问题。除了配置之外,我无法注入依赖项 类库包含要调用的代码: public interface IMyClient { Task DoSomething(Request request); } public class MyClient : IMyClient { private readonly MyClientConfig _config; private readonly ILogger<MClient

我在创建控制台程序以调用引用类库中的enrol方法时遇到问题。除了配置之外,我无法注入依赖项

类库包含要调用的代码:

public interface IMyClient
{
    Task DoSomething(Request request);
}

public class MyClient : IMyClient
{
    private readonly MyClientConfig _config;
    private readonly ILogger<MClient> _logger;
    private readonly HttpClient _client;

    public MyClient()
    {

    }

    public MyClient(MyClientConfig config, ILogger<MyClient> logger, HttpClient client)
    {
        _config = config;
        _logger = logger;
        _client = client;
    }

    public async Task DoSomething(Request request)
    {
        // BREAKPOINT HERE HAS config (id = 1) but logger & client are null
    }
}
公共接口IMyClient
{
任务剂量测量(请求);
}
公共类MyClient:IMyClient
{
私有只读MyClientConfig\u config;
专用只读ILogger\u记录器;
私有只读HttpClient\u客户端;
公共MyClient()
{
}
公共MyClient(MyClientConfig配置、ILogger记录器、HttpClient客户端)
{
_config=config;
_记录器=记录器;
_客户=客户;
}
公共异步任务DoSomething(请求)
{
//此处的断点具有配置(id=1),但记录器和客户端为空
}
}
和控制台程序

class Program
{
    private static IServiceProvider _serviceProvider;
    static void Main(string[] args)
    {
        RegisterServices();
        IServiceScope scope = _serviceProvider.CreateScope();

        var request = new Request()
        {
            Id = 1
        };

        scope.ServiceProvider.GetRequiredService<IMyClient>().DoSomething(request);

        DisposeServices();
    }

    private static void RegisterServices()
    {
        var myClientConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)
            .Build().GetSection("MyClient").Get<MyClientConfig>();


        var services = new ServiceCollection();
        services.AddSingleton<IMyClient, MyClient>();
        services.AddSingleton<IMyClientConfig>(myClientConfig);
        _serviceProvider = services.BuildServiceProvider(true);
    }

    private static void DisposeServices()
    {
        if (_serviceProvider == null)
        {
            return;
        }
        if (_serviceProvider is IDisposable)
        {
            ((IDisposable)_serviceProvider).Dispose();
        }
    }
}
类程序
{
专用静态IServiceProvider\u服务提供商;
静态void Main(字符串[]参数)
{
RegisterServices();
IServiceScope范围=_serviceProvider.CreateScope();
var请求=新请求()
{
Id=1
};
scope.ServiceProvider.GetRequiredService().DoSomething(请求);
处置服务();
}
私有静态无效注册表服务()
{
var myClientConfig=new ConfigurationBuilder()
.AddJsonFile(“appsettings.json”,true,true)
.Build().GetSection(“MyClient”).Get();
var services=newservicecolection();
services.AddSingleton();
services.AddSingleton(myClientConfig);
_serviceProvider=services.BuildServiceProvider(true);
}
私有静态void DisposeServices()
{
if(_serviceProvider==null)
{
返回;
}
如果(_serviceProvider可识别)
{
((IDisposable)u serviceProvider.Dispose();
}
}
}
我试着加进去

services.AddSingleton(新的HttpClient())

注入HttpCLient,但没有效果


任何关于测试引用项目中DoSomething调用的帮助或建议

您没有在
服务中配置
记录器
HttpClient
。您可能还缺少一个附加的Nuget软件包,
Microsoft.Extensions.Logging.Console
——如果缺少,请安装它,因为您提到这是一个控制台应用程序

按如下方式修改您的代码:

private static void RegisterServices()
{
var myClientConfig=new ConfigurationBuilder()
.AddJsonFile(“appsettings.json”,true,true)
.Build().GetSection(“MyClient”).Get();
var services=newservicecolection();
services.AddSingleton();
//配置日志记录服务
services.AddLogging(cfg=>cfg.AddConsole())
.AddTransient();
//配置HttpClient-可能需要一些构造函数参数,具体取决于您的用例
AddSingleton(新的HttpClient());
_serviceProvider=services.BuildServiceProvider(true);
}
另外,非常重要:删除
MyClient
中的空构造函数!你永远不会想要那一击!事实上,程序在调试时崩溃要比命中构造函数好得多,因为它会产生工作的外观,就像您现在所处的情况一样

添加
services.AddSingleton(新的HttpClient())时代码“没有做任何不同”的原因代码是由于您的空构造函数造成的-由于
记录器
服务尚未配置,DI框架无法匹配正确的构造函数-因此,空构造函数没有得到有意义的错误,而是运行了(因为它始终匹配)-导致调试痛苦和痛苦


另一方面,我建议大家阅读一下DI是如何在底层工作的(甚至可以构建自己的DI容器,一个非常简单的容器,用于实践。不要在生产中使用自己的DI容器!)。这是一篇很好的文章,作者实际上是发明这种东西的人:

MyClient
中的非默认构造函数被击中了吗?没有。如果我删除了空构造函数,尽管该方法没有命中,您使用的是什么DI容器框架?microsoft.extensions.dependencyinjection,这就是您的意思吗?@downvoter,出于好奇,为什么这个问题被否决了?我真的看不出这张海报在问这个问题时犯了什么错误。。。请您解释一下,这样这个用户(坦率地说,我也是)就可以学习了?非常感谢。