Home > Software engineering >  Having trouble with AddSingleton and how it actually works?
Having trouble with AddSingleton and how it actually works?

Time:09-23

I have the following line in my Startup.cs file:

services.AddSingleton<IFirewallPorts>(Configuration.GetSection("FirewallPorts").Get<FirewallPorts>());

This reads data from the FirewallPorts section of my appsettings.json file and assigns that data to the FirewallPorts class.

I understand AddSingleton to be: creates a single instance throughout the application. It creates the instance for the first time and reuses the same object in the all calls.

Now if I directly inject the FirewallPorts into a class like this, it works fine.

public class SomeClass : ISomeClass
{
    private readonly IFirewallPorts _fireWallPorts;

public SomeClass(IFirewallPorts fireWallPorts)
{
    _fireWallPorts = fireWallPorts;
}

But if I do this:

FirewallPorts fp = new FirewallPorts();
SomeClass sc = new SomeClass(fp);

Everything in fp is null.

Why would this be and how would I fix this?

Thanks!

CodePudding user response:

Why would this be

Most probably because the default constructor of FirewallPorts doesn't do any intialization of the fields or properties.

how would I fix this?

Implement the constructor to actually initialize the object as expected, or set the properties yourself after you have created the instance:

FirewallPorts fp = new FirewallPorts() { SomeProperty = "somevalue.." };

The Configuration.GetSection.Get method does the latter for you behind the scenes, i.e. it creates and instance and set its properties according to what you specified in the configuration file.

CodePudding user response:

There is no magic with Dependency Injection. When you do:

FirewallPorts fp = new FirewallPorts();
SomeClass sc = new SomeClass(fp);

You are not using any DI implementation. You're just creating the class with the default properties which in your case is null values.

Lets say for example you're using asp.net. Asp.net is using the DI infrastructure to create instances of your classes in response to http requests.

As an example you could do the same thing in your startup code if you built the service provider:

public void ConfigureServices(IServiceCollection services)
{ 
   
   services.AddSingleton<IFirewallPorts>(Configuration.GetSection("FirewallPorts").Get<FirewallPorts>());
   
   IServiceProvider provider = services.BuildServiceProvider();
   
   IFirewallPorts ports = provider.GetRequiredService<IFirewallPorts>();
}

Your "ports" instance above would now have valid values. To state this another way, you shouldn't be manually creating IFirewallPorts instances.

  • Related