【问题标题】:How do I combine Dependency Injection with Configuration Binding in .Net Core?如何在 .Net Core 中将依赖注入与配置绑定结合起来?
【发布时间】:2023-03-21 03:15:01
【问题描述】:

我之前并没有真正使用过依赖注入,但它似乎很适合我现在正在构建的 .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 强类型对象,Source 和Destination 部分应分别解析为强类型FileLocation 对象,无需手动映射到JSON 字段名称。下面的代码实现了这一点(使用顶级 Routes 类来包含列表):

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 框架,或者有没有办法使用可用的第一方框架来实现这一点?

【问题讨论】:

标签: c# json .net-core dependency-injection inversion-of-control


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    一种方法是使用 HostBuilder 类。 Here你可以找到一个例子。

    【讨论】:

    • 我按照您提供的链接进行操作,HostBuilder 看起来很有趣,但对于我所询问的情况,与在我的 Program.cs 中实现 ConfigureServices() 相比,我看不出它的工作方式有何不同
    • 如果this 不是您的意思,那么它可能不支持开箱即用。
    【解决方案3】:

    我最终采用的方法是将选项分离到它们自己严格的 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);
        }
    }
    

    这样,我仍然可以将各个类相互隔离以进行单元测试,并在高层次上保留大部分依赖关系图。

    【讨论】:

      猜你喜欢
      • 2017-05-10
      • 2017-12-14
      • 2016-05-22
      • 1970-01-01
      • 2021-07-15
      • 2022-01-24
      • 2021-10-23
      • 1970-01-01
      • 2021-02-02
      相关资源
      最近更新 更多