c# - 为什么 .net 核心依赖注入对我不起作用?
问题描述
我正在尝试在我的控制台应用程序中使用 .net core DI。当我写这样的东西时(下面的代码位于我的 Program.cs 中):
private static IServiceCollection ConfigureServices()
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
IServiceCollection services = new ServiceCollection();
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
ConfigurationOptions configurationOptions = new ConfigurationOptions
{
ConnectionString = "my-connection-string",
StoredProceduresPath = "my-path",
PathToGeneralFolder = "D:\\XmlFiles",
PathToInvalidFolder = "D:\\InvalidXmlFiles",
LogName = "Log",
Source = "Source",
SecretHashPassword = "my-sercet-password",
DataAccessTimeoutMs = 30_000
};
IOptions<ConfigurationOptions> options = Options.Create(configurationOptions);
DatabaseTransactionManager databaseTransactionManager = new DatabaseTransactionManager();
DbContext DbContext = new DbContext(
options,
databaseTransactionManager);
UserRepository userRepository = new UserRepository(DbContext);
SoftwareRepository softwareRepository = new SoftwareRepository(DbContext);
SoftwareModuleRepository softwareModuleRepository = new SoftwareModuleRepository(DbContext);
DeviceRepository deviceRepository = new DeviceRepository(DbContext);
LoggerService loggerService = new LoggerService(options);
XmlService xmlService = new XmlService(options);
SqlService sqlService = new SqlService(
deviceRepository,
softwareModuleRepository,
softwareRepository);
FolderService folderService = new FolderService(
options,
cancellationTokenSource,
cancellationTokenSource.Token,
sqlService,
loggerService,
xmlService);
services.AddScoped(serivceProvider => folderService);
return services;
}
我的 FolderService 已正确初始化并且可以正常工作,但是当我尝试以“正常”方式注入所有内容时(也位于我的 Program.cs 中):
private static IServiceCollection ConfigureServices()
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
IServiceCollection services = new ServiceCollection();
services.Configure<ConfigurationOptions>(configOptions => configuration.GetSection("ConfigurationOptions"));
services.AddScoped<CancellationTokenSource>();
services.AddScoped<ITransactionManager, DatabaseTransactionManager>();
services.AddScoped<IDbContext, DbContext>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<ISoftwareRepository, SoftwareRepository>();
services.AddScoped<ISoftwareModuleRepository, SoftwareModuleRepository>();
services.AddScoped<IDeviceRepository, DeviceRepository>();
services.AddScoped<ILoggerService, LoggerService>();
services.AddScoped<IXmlService, XmlService>();
services.AddScoped<ISqlService, SqlService>();
services.AddScoped<IFolderService, FolderService>();
return services;
}
...在调试时,我看到 FolderService 为空。我究竟做错了什么?我的 appsettings.json 文件如下所示:
{
"ConfigurationOptions": {
"ConnectionString": "some-connection-string",
"StoredProceduresPath": "some-path",
"PathToGeneralFolder": "D:\\XmlFiles",
"PathToInvalidFolder": "D:\\InvalidXmlFiles",
"LogName": "Log",
"Source": "Source",
"SecretHashPassword": "my-sercet-password",
"DataAccessTimeoutMs": 30000
}
}
FolderService 类(构造函数部分):
public class FolderService : IFolderService
{
private readonly string generalFolder;
private readonly CancellationTokenSource cancellationTokenSource;
private readonly CancellationToken cancellationToken;
private readonly ISqlService sqlService;
private readonly ILoggerService loggerHelper;
private readonly IXmlService xmlHelper;
public FolderService(IOptions<ConfigurationOptions> options,
CancellationTokenSource cancellationTokenSource, CancellationToken cancellationToken,
ISqlService sqlService, ILoggerService loggerHelper, IXmlService xmlHelper)
{
this.generalFolder = options.Value.PathToGeneralFolder;
this.cancellationTokenSource = cancellationTokenSource;
this.cancellationToken = cancellationTokenSource.Token;
this.sqlService = sqlService;
this.loggerHelper = loggerHelper;
this.xmlHelper = xmlHelper;
}
}
完整程序.cs
private static IServiceCollection ConfigureServices()
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
IServiceCollection services = new ServiceCollection();
#region As it must be
services.Configure<ConfigurationOptions>(configOptions => configuration.GetSection("ConfigurationOptions"));
services.AddScoped<CancellationTokenSource>();
services.AddScoped<ITransactionManager, DatabaseTransactionManager>();
services.AddScoped<IDbContext, DbContext>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<ISoftwareRepository, SoftwareRepository>();
services.AddScoped<ISoftwareModuleRepository, SoftwareModuleRepository>();
services.AddScoped<IDeviceRepository, DeviceRepository>();
services.AddScoped<ILoggerService, LoggerService>();
services.AddScoped<IXmlService, XmlService>();
services.AddScoped<ISqlService, SqlService>();
services.AddScoped<IFolderService, FolderService>();
#endregion
#region As it works by now
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
ConfigurationOptions configurationOptions = new ConfigurationOptions
{
ConnectionString = "not-important",
StoredProceduresPath = "not-important",
PathToGeneralFolder = "D:\\XmlFiles",
PathToInvalidFolder = "D:\\InvalidXmlFiles",
LogName = "ButsenkoLog",
Source = "NektarinSource",
SecretHashPassword = "my-sercet-password",
DataAccessTimeoutMs = 30_000
};
IOptions<ConfigurationOptions> options = Options.Create(configurationOptions);
DatabaseTransactionManager databaseTransactionManager = new DatabaseTransactionManager();
DbContext dbContext = new DbContext(
options,
databaseTransactionManager);
UserRepository userRepository = new UserRepository(dbContext);
SoftwareRepository softwareRepository = new SoftwareRepository(dbContext);
SoftwareModuleRepository softwareModuleRepository = new SoftwareModuleRepository(dbContext);
DeviceRepository deviceRepository = new DeviceRepository(dbContext);
LoggerService loggerService = new LoggerService(options);
XmlService xmlService = new XmlService(options);
SqlService sqlService = new SqlService(
deviceRepository,
softwareModuleRepository,
softwareRepository);
FolderService folderService = new FolderService(
options,
cancellationTokenSource,
cancellationTokenSource.Token,
sqlService,
loggerService,
xmlService);
services.AddScoped(serivceProvider => folderService);
#endregion
return services;
}
static void Main(string[] args)
{
IServiceCollection services = ConfigureServices();
ServiceProvider serviceProvider = services.BuildServiceProvider();
FolderService folderService = serviceProvider.GetService<FolderService>();
HostFactory.Run(configurator =>
{
configurator.RunAsLocalSystem();
configurator.Service<FolderService>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => folderService);
serviceConfigurator.WhenStarted((service, hostControl) =>
{
service.Start();
return true;
});
serviceConfigurator.WhenStopped((service, hostControl) =>
{
service.Stop();
return true;
});
});
});
}
解决方案
您将您的课程注册为,IFolderService
但您尝试通过调用serviceProvider.GetService<FolderService>();
它应该是的方式通过服务获取它;
var folderService = serviceProvider.GetService<IFolderService>();
只要所有构造函数参数都成功解析,你就可以开始了。
推荐阅读
- javascript - 为什么我向 Spotify API 发出请求的 UseEffect 会出现错误 429?
- swift - 如何在 Swift 中拥有同名的变量和函数
- laravel-8 - laravel 将 value='laravel' 转换为 value='URL'
- typescript - 如何使用 Sequelize 键入聚合函数
- assembly - 访问 PIT (?) IO 端口 44h 和 46h - 这些端口有什么作用?
- python - python dirsync (rsync) 对子文件夹不起作用
- javascript - Discord Bot 没有响应
- node.js - 从处理中执行的 bash 脚本中执行 nodejs
- visual-studio-code - VSCODE:SFTP 连接“未找到配置。(文件:///...”
- sql-server - 使用快照隔离防止 SQL 视图被冗长的删除/插入事务阻塞