繁体   English   中英

使用 DI 模拟调用.Net Core class 库

[英]Mock call to .Net Core class library with DI

我无法创建一个控制台程序来调用引用的 class 库中的注册方法。 除了配置之外,我无法注入依赖项。

Class 库包含要调用的代码:

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
    }
}

和控制台程序

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();
        }
    }
}

我尝试添加

services.AddSingleton<HttpClient>(new HttpClient());

获取 HttpCLient 注入但无济于事。

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

您没有在services中配置LoggerHttpClient 您还可能缺少一个额外的 Nuget package, Microsoft.Extensions.Logging.Console - 如果它丢失,请安装它,因为您提到这是一个控制台应用程序

修改您的代码如下:

    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>();

        // Configure logging service
        services.AddLogging(cfg => cfg.AddConsole())
                .AddTransient<MyClient>();

        // Configure HttpClient - might need some constructor params, depending on your use case
        services.AddSingleton<HttpClient>(new HttpClient());

        _serviceProvider = services.BuildServiceProvider(true);
    }

另外,非常重要:删除MyClient中的空构造函数 永远不想要那一击,事实上,程序在调试中崩溃比击中构造函数要好得多,因为它会产生工作的外观- 就像你现在所处的情况一样。

添加services.AddSingleton<HttpClient>(new HttpClient());时代码“没有做任何不同”的原因代码是因为您的空构造函数- 由于仍未配置Logger服务,DI 框架无法匹配正确的构造函数 - 因此空构造函数运行(因为它总是匹配)而不是得到有意义的错误 - 导致调试痛苦和苦难

顺便说一句,我建议阅读 DI 如何在下面工作(甚至可以构建自己的 DI 容器,一个非常简单的容器,用于练习。不要在生产中使用自己的 DI 容器。),这是一篇好文章:by实际上发明了这些东西的人: https://martinfowler.com/articles/injection.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM