繁体   English   中英

如何将依赖注入与.Net Core 中的配置绑定相结合?

[英]How do I combine Dependency Injection with Configuration Binding in .Net Core?

我以前并没有真正使用过依赖注入,但它似乎很适合我现在正在构建的 .Net Core 项目。 它是一个容器化的非 ASP 服务(因此本质上是一个控制台应用程序),其配置由 JSON 文件驱动,如下所示:

{
  "Routes": [
    {
      "Name": "What's in a name?",
      "Description": "This is a description",

      "Source": {
        "Path": "SomePath/Read"
      },

      "Destination": {
        "Path": "SomePath/Write"
      }
    }
  ]
}

Routes可以指定n条路由。 每个都应解析为Route强类型 object,Source 和 Destination 部分应分别解析为强类型FileLocation object,没有手动映射到 JSON 字段名称。 下面的代码实现了这一点(使用顶级Routes class 来包含列表):

new ConfigurationBuilder()
    .AddJsonFile(FileRoutesConfigFile, optional: false, reloadOnChange: true)
    .Build()
    .Get<Routes>()

但是,我希望配置类受益于 Microsoft DependencyInjection 框架以获取应用程序服务(例如FileLocation的类似内容):

public class FileLocation {
    public string Path { get; set; }
    private IAppConfiguration AppConfiguration { get; }

    public FileLocation(IAppConfiguration appConfiguration) {
        AppConfiguration = appConfiguration;
    }
}

我看不到这样做的方法(当没有无参数构造函数时它完全失败)。 我是否需要使用不同的 DI 框架,或者有没有办法使用可用的第一方框架来实现这一点?

我认为 Autofac 或 Scrutor 可能会有帮助。 IServiceCollection 可能没有它。

一种方法是使用 HostBuilder class。您可以在此处找到示例。

我最终采用的方法是将选项分离到它们自己的严格 POCO 类中,然后创建工厂来生成更复杂的业务类,并将它们作为输入。 工厂可以由服务提供者构建,并注入到需要生成 JSON 配置类的类中。 例如,我的一个工厂看起来像这样:

public interface IBusinessClassFactory
{
    IBusinessClass GetBusinessClass(BusinessClassConfig config);
}

public class BusinessClassFactory : IBusinessClassFactory
{
    public BusinessClassFactory(AppConfig appConfig, ISubclassFactory subclassFactory,
        IServiceProvider serviceProvider)
    {
        AppConfig = appConfig;
        SubclassFactory = subclassFactory;
        ServiceProvider = serviceProvider;
    }

    public AppConfig AppConfig { get; }
    public ISubclassFactory SubclassFactory { get; }
    public IServiceProvider ServiceProvider { get; }

    public IBusinessClass GetBusinessClass(BusinessClassConfig config)
    {
        var logger = ServiceProvider.GetRequiredService<ILogger<FileLocation>>();
        return new BusinessClass(logger, AppConfig, SubclassFactory, config);
    }
}

这样,我仍然可以将类彼此隔离以进行单元测试,并在较高级别保留大部分依赖项 map。

暂无
暂无

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

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