为什么.net核心依赖项注入对我不起作用?

时间:2019-12-20 15:51:20

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

我正在尝试在控制台应用程序中使用.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为空。我究竟做错了什么? 我的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;
        }
}

完整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();

            #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;
                    });
                });
            });
        }

1 个答案:

答案 0 :(得分:2)

您将课程注册为IFolderService,但是您尝试通过致电serviceProvider.GetService<FolderService>();来通过服务获取课程 应该是

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

只要所有构造函数参数都能成功解析,就可以了。