Reputation: 1094
i have a .net core 2.0 application which has an appsettings.json file which holds the configuration for the service.
In my startup script i added this code:
services.Configure<AppConfiguration>(Configuration.GetSection("AppConfiguration"));
Now the settings binded. And i could access the Configuration from any controller, for example like this:
public class HomeController : Controller
{
private AppConfiguration _mySettings;
/// <summary>
/// Constructor binds the AppConfiguration
/// </summary>
/// <param name="settings"></param>
public HomeController(IOptionsSnapshot<AppConfiguration> settings)
{
_mySettings = settings.Value;
this.IsOnline = _mySettings.MQTTSettings.Active && _mySettings.MicroserviceID != 0;
}
}
Now there is my question. I also would like to use the IOptionsSnapshot from normal classes which aren't extend the abstract Controller Class. For example like this:
public class TestClass
{
public TestClass(IOptionsSnapshot<AppConfiguration> optionsSnapshot)
{
//DO SOME STUFF WITH THE Snapshot
}
}
The Problem is, that i have to pass the IOptionsSnapshot to the Testclass when i try to create an object from it.
TestClass t = new TestClass(NEEDS AN IOptionsSnapsot Object);
So how can i get the IOptionsSnapshot or is there any other possibility to put it into the TestClass? How could i access it in this case?
For example at the Startup Routine i don't have any Controller Call before, so i need the IOptionsSnapshot first in the Class.
Thanks for your help.
Upvotes: 3
Views: 5005
Reputation: 387825
You are simply not supposed to create service classes manually using new
. The point about dependency injection is to not have the responsibility of having to create types and as such pass the correct dependencies to it. Instead, you are supposed to ask for an instance of your type and have the dependency container resolve the dependencies for you.
So wherever you are attempting to do new TestClass
, you should instead inject a TestClass
instance. This requires your TestClass
to be registered with the service collection, and this also requires your consumer of the TestClass
to be also resolved through dependency injection. Basically, everything that are not data classes is supposed to be resolved through dependency injection.
For example, in your Startup
’s ConfigureServices
method, you want to register your TestClass
as a service:
services.AddTransient<TestClass>();
Then, in your controller, you might want to use the TestClass
, so you inject it:
public class HomeController : Controller
{
private readonly TestClass _testClass;
public HomeController(TestClass testClass)
{
_testClass = testClass;
}
public IActionResult Index()
{
var data = _testClass.DoSomething();
return View(data);
}
}
And because TestClass
is resolved through dependency injection, it can have dependencies as well that will be resolved automatically:
public class TestClass
{
private readonly IOptionsSnapshot<AppConfiguration> _options;
public TestClass(IOptionsSnapshot<AppConfiguration> optionsSnapshot)
{
_options = optionsSnapshot;
}
public SomeViewModel DoSomething()
{
// access the options
var active = _options.Value.MQTTSettings.Active;
// it’s fine to actively create *data* objects
return new SomeViewModel()
{
IsActive = active,
};
}
}
Upvotes: 3