65.9K
CodeProject 正在变化。 阅读更多。
Home

将依赖注入添加到 .NET 控制台应用程序(和测试)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2022 年 8 月 6 日

CPOL

3分钟阅读

viewsIcon

9871

如何在 .NET 控制台应用程序中添加 DI

您可能已经注意到,依赖注入 (DI) 如今已成为事实上的标准,并且可以说理所当然,因为它(如果使用得当)会产生可测试、可更改、解耦的代码库。 但也许一个挑战(至少在 ASP.NET 生态系统中)是,当我们创建一个新的 ASP.NET 项目时,很多引导程序都得到了照顾,因此在自动化测试或其他顶级项目中设置 DI 可能会令人困惑和不清楚,这些项目没有获得 ASP.NET Web 项目提供的开箱即用的脚手架。 关于如何执行此操作的指南有很多,但这是一个简洁明了的指南。

哦,在进一步讨论之前,我想提一下,这里显示的示例将使用 Microsoft 提供的、与 ASP.NET Core 项目一起提供的简单 DI 容器。 这里涵盖的概念与其他容器类似,但代码本身会略有不同。

首先,让我们订购一些包

在版本控制方面,您很可能已经在解决方案中的其他项目中安装了这些包。 因此,只要您没有在项目之间混合和匹配 .NET 版本,保持版本相同是有意义的。 因此,我将只列出您需要的软件包,并让您找出合适的版本。

  1. Microsoft.Extensions.Configuration
  2. Microsoft.Extensions.Configuration.Json
  3. Microsoft.Extensions.DependencyInjection
  4. Microsoft.Extensions.DependencyInjection.Abstractions
  5. Microsoft.Extensions.Options

添加您的应用程序设置

在配置方面,您可能在现有 ASP.NET Web 项目中的 appsettings.*.json 文件中定义了一些自定义应用程序设置。 您需要将其添加到新的(简陋的)项目中,以便应用相同的设置。 您有几个选项可以执行此操作

  1. 为您的新项目创建一个自定义设置文件;
  2. 将现有的 appsettings.json 文件从您的 Web 项目复制到您的新项目;或
  3. 从现有的 appsettings.json 文件添加链接到您的新项目

我通常更喜欢选项 3,因此您在主 Web 项目的 appsetting.json 文件中所做的任何更改也会在您的新项目中生效,并且您无需维护两个(或更多)config 文件。

* 在 Rider 或 VS for Mac 中,此外观可能略有不同,但它应该仍然存在。

全部设置好

在这里,我建议创建一个 xxxBootstrapper 类来处理 DI 容器的引导程序和任何其他设置,其中 xxx 是您的项目的前缀。 例如,如果这是一个测试项目,您可以将其称为 TestBootstrapper

例如

    public static class TestBootstrapper
    {
        public static void Bootstrap(IServiceCollection services)
        {
            // todo: Add any test services
        }
    }

太好了,但我实际上如何创建 Iservicecollection 实例?

礼貌地询问 :) 严肃地说,只需创建一个新的 ServiceCollection,它是 IServiceCollection 的具体实现。

    public static class ServiceProviderFactory
    {
        public static IServiceProvider CreateServiceProvider()
        {
            var services = new ServiceCollection();

            LibraryBootstrapper.Bootstrap(services);
            TestBootstrapper.Bootstrap(services);

            return services.BuildServiceProvider();
        }
    }

由于我们可能会在每个测试中执行此操作,并且引导逻辑可能会随着解决方案的增长而增长,因此为了方便起见,我将其放置在工厂内部。

整合

这是它。 :) 请注意,SetupTest 是 NUnit 特定的属性,它们可能与您根据所使用的测试框架需要使用的属性不同 - 尽管您应该使用 NUnit,因为所有其他属性都很愚蠢。

*** 以上声明只是一个玩笑。 使用您喜欢的任何测试框架。

using ConsoleDependencyInjection.Library;
using Microsoft.Extensions.DependencyInjection;

namespace ConsoleDependencyInjection.Tests;

public class MyServiceTests
{
    private IMyService _sut;

    [SetUp]
    public void Setup()
    {
        _sut = ServiceProviderFactory
            .CreateServiceProvider()
            .GetService<IMyService>();
    }

    [Test]
    public void Test1()
    {
        Assert.DoesNotThrow(() =>
        {
            _sut.DoTheThing();
        });
    }
}

Setup 方法(在每个测试之前运行)中,我们从我们之前创建的工厂创建一个服务提供程序的实例,并使用 Service Locator 方法进行 DI,要求提供程序提供我们要测试的服务。 要查看整个过程的实际效果,您可以查看 Github 上的存储库。

感谢您的阅读! 再见!

© . All rights reserved.