我正在尝试在控制台应用程序中使用.net核心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为null。我究竟做错了什么?
我的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;
}
}
完整程序
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>();
只要所有构造函数参数都能成功解析,您就可以使用。