2

Below is my sample code. I have this class whose constructor takes an IConfigurationRoot parameter and uses it to set a private field:

public class MyClass
{
    private IConfigurationRoot _configuration;

    public class MyClass(IConfigurationRoot configuration)
    {
        // I believe this has been injected
        _configuration = configuration;
    }
}

Now I want to instantiate that class:

public class AnotherClass
{
    private IConfigurationRoot _configuration;
    private MyClass myclass;

    public SomeMethod()
    {
         // My _configuration here gets null in the debugger
         MyClass myclass = new MyClass(_configuration);

         // Rest of method omitted...
    }
}

How do I properly instantiated that class so that it doesn't end up being null?

Rufus L
  • 36,127
  • 5
  • 30
  • 43

3 Answers3

1

Follow this process:

1.) What I have done is map a section of the AppSettings.json file to an object.

A.) Add the configuration settings to json file.

"MyConfiguration": {

  "DBServer": "MyDBServer",
  "DBName": "MyDatabase"
}

B.) Create a class to use strongly typed configurations.

public class MyConfiguration
{
     public string DBServer { get; set;}
     public string DBName { get; set;}
}

C.) Map the JSON configurations to the MyConfiguration object in the Startup class.

public class Startup
{

   //Make sure you add this.
   public IConfigurationRoot Configuration { get; }

   public void ConfigureServices(IServiceCollection services)
   {
       ...

       var configSection = Configuration.GetSection("MyConfiguration");

       services.Configure<MyConfiguration>(configSection);

       //Use one of the following.            
       Services.AddScoped<MyClass>();
       Services.AddTransient<MyClass>();
       Services.AddSingleton<MyClass>();
       Services.AddInstance<MyClass>();
       ...
   }
}

See this link for an explanation of the differences between

`AddSingleton()`
`AddScopped()`
`AddInstance()`
`AddTransient()`

2.) Change MyClass to have MyConfiguration object as a parameter of the MyClass constructor.

//add this using statement and corresponding package
//"Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.1"
using Microsoft.Extensions.Options;

public class MyClass
{
    private MyConfiguration _configuration;


    public MyClass(IOptions<MyConfiguration> configuration)
    {
        _configuraiton = configuraiton.Value;
    }
}

3.) Add MyClass as a parameter of the AnotherClass constructor. Dependency Injection will create the MyClass or reuse it depending on the scope of the object and how you setup that up in the Startup.ConfifureServices() method.

public class AnotherClass
{

    private MyClass _myclass;

    public AnoherClass(MyClass myclass)
    {
        _myclass= myclass;
    }

    public SomeMethod()
    {

       //Use myClass here and you don't need to instantiate it.
       _myclass
       ....
    }
}
aaronR
  • 1,557
  • 2
  • 16
  • 26
0

You doing a couple of things.

1 - You are re-declaring your class variable myclass as a local variable in your SomeMethod. You should use the myclass variable you already declared as a class variable. To do that, make this line

MyClass myclass = new MyClass(_configuration);

Like this

myclass = new MyClass(_configuration);

2 - You are not instantiating your IConfigurationRoot, so it is null before inject it at all. You should be able to instantiate it however you want (ConfigurationBuilder like @Sach suggested, or _configuration = ConfigurationBuilder.Build() as @Eldho suggested), but you need to instantiate it before you inject it if you dont want it to be null.

Michael Sharp
  • 496
  • 3
  • 10
0

Here, it would be best if you use an IOC container like Autofac or Unity or the built-in container in ASP.NET core(if you are using core). You would need to register your IConfigurationRoot interface and its implemented class with the IOC container. After this, inject your MyClass object using the IOC container(in the constructor, or in the method, as per your best scenario). This way, you would never face a problem.

tech-y
  • 1,829
  • 2
  • 16
  • 26
  • ....as opposed to just going `_configuration = ConfigurationBuilder.Build()`? IoC are an example of mass psychosis –  Sep 07 '17 at 23:17
  • I inferred the problem was related to avoid passing null dependencies, and instantiate objects at the right place. I did not suggest on how to create the configuration object. _configuration = ConfigurationBuilder.Build() would still be needed. – tech-y Sep 08 '17 at 09:20