c# - 为什么 .net 核心依赖注入(inject)对我不起作用?

标签 c# asp.net .net asp.net-core dependency-injection

我正在尝试在我的控制台应用程序中使用 .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 已正确初始化并且可以正常工作,但是当我尝试以“正常”方式注入(inject)所有内容时(也位于我的 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;
                    });
                });
            });
        }

最佳答案

您将您的类(class)注册为 IFolderService但是您尝试通过调用 serviceProvider.GetService<FolderService>(); 来通过服务获取它
它应该是;

var folderService = serviceProvider.GetService<IFolderService>();

只要所有构造函数参数成功解析,你就可以开始了。

关于c# - 为什么 .net 核心依赖注入(inject)对我不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59428009/

相关文章:

c# - CaSTLe Windsor 从 2.5 升级到 3.3 (ASP.Net MVC)

c# - Visual Studio 2010 中的构建问题

ASP.NET 隐藏字段与不可见文本框

asp.net - 使用 itext (itextsharp) 替换一个 PDF 模板页面上的多个不同图像

c# - Facebook 使用 C# 使用 Graph API 检索数据

c# - 检查更新语句是否成功

c# - log4net - 记录通过 COM 互操作调用的 dll

c# - 使用指定为 "utf-16"的编码解析 xml 时出现 XmlException

c# - 属性的内部 setter 可以序列化吗?

c# - 在 C# 中识别 jpeg 的颜色配置文件