如何在 .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
强类型对象,源和目标部分应分别解析为强类型 FileLocation
对象,无需手动映射到 JSON 字段名称。下面的代码实现了这一点(使用顶级 Routes
class 来包含列表):
new ConfigurationBuilder()
.AddJsonFile(FileRoutesConfigFile, optional: false, reloadOnChange: true)
.Build()
.Get<Routes>()
但是,我希望配置 classes 能够从 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。 Here你可以找到一个例子。
我最终采用的方法是将选项严格分为自己的 POCO 类,然后创建工厂来生产更复杂的业务 类,并将这些作为输入。工厂可以由服务提供者构建,并注入到需要生产JSON-configured类的类中。例如,我的一个工厂是这样的:
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);
}
}
这样,我仍然可以将 类 彼此隔离以进行单元测试,并在较高级别保留大部分依赖关系图。
我以前并没有真正使用过依赖注入,但它似乎很适合我现在正在构建的 .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
强类型对象,源和目标部分应分别解析为强类型 FileLocation
对象,无需手动映射到 JSON 字段名称。下面的代码实现了这一点(使用顶级 Routes
class 来包含列表):
new ConfigurationBuilder()
.AddJsonFile(FileRoutesConfigFile, optional: false, reloadOnChange: true)
.Build()
.Get<Routes>()
但是,我希望配置 classes 能够从 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。 Here你可以找到一个例子。
我最终采用的方法是将选项严格分为自己的 POCO 类,然后创建工厂来生产更复杂的业务 类,并将这些作为输入。工厂可以由服务提供者构建,并注入到需要生产JSON-configured类的类中。例如,我的一个工厂是这样的:
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);
}
}
这样,我仍然可以将 类 彼此隔离以进行单元测试,并在较高级别保留大部分依赖关系图。