4

I'm trying to use the .net core DI in my console app. When I write something like this (the code below is located in my 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;
    }

my FolderService is properly initialized and works with no problems, but when I try to inject everything in a "normal" way (located in my Program.cs as well):

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

...while debugging I see that FolderService is null. What am I doing wrong? my appsettings.json file looks like this:

{
  "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 class (constructor part):

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

Full 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;
                    });
                });
            });
        }
16
  • Where do you inject it? Could you share Program.cs? Commented Dec 20, 2019 at 15:58
  • All the parameters in your FolderService contructor also need to be injected dependencies/services. Is this true? Commented Dec 20, 2019 at 15:59
  • This shouldnt have anything to do with your appsettings... Does FolderService implement IFolderService? Commented Dec 20, 2019 at 15:59
  • @ilkerkaran actually it is injected in Program.cs, I get this FolderService instance in Main method IServiceCollection services = ConfigureServices(); ServiceProvider serviceProvider = services.BuildServiceProvider(); FolderService folderService = serviceProvider.GetService<FolderService>(); Commented Dec 20, 2019 at 16:02
  • 2
    I will add it as an aswer if you are happy with it Commented Dec 20, 2019 at 16:39

1 Answer 1

5

You Register your class as IFolderService but you try to get it via service by calling like serviceProvider.GetService<FolderService>(); It should be;

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

And as long as all constructor parameters resolve successfully you are good to go.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.