Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does .net core Dependency injection not work for me?

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;
                    });
                });
            });
        }
like image 372
el_nektarin Avatar asked Oct 15 '25 20:10

el_nektarin


1 Answers

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.

like image 155
ilkerkaran Avatar answered Oct 18 '25 11:10

ilkerkaran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!