I have a class library where I want to access a Connectionstring from appsettings.json.
appsettings.json :
"DatabaseSettings": {
"ConnectionString": "Server=.;Database=Test;Trusted_Connection=True;"
},
In startup.cs I have the following code:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<DatabaseSettings>(Configuration.GetSection("DatabaseSettings"));
services.AddOptions();
services.AddTransient<IConnectionOption, Class1>();
}
And in class library
IConnectionOption.cs
public interface IConnectionOption
{
void ReadValue();
}
Class1.cs
public class Class1 : IConnectionOption
{
private readonly DatabaseSettings test;
public Class1(IOptions<DatabaseSettings> dbOptions)
{
test = dbOptions.Value;
}
public void ReadValue()
{
var r = test;
}
}
Now from index.cshtml I want to Invoke the class Library Class1
public class IndexModel : PageModel
{
public void OnGet()
{
Class1 test = new Class1();
test.ReadValue();
}
}
But of course that doesnt work since there are no Constructor taking zero parameters, I don´t think I should add IOptions as an parameter. But how do I invoke the class library to read the connectionstring? (When I get this to work I will of course read data and return instead of the connectionstring). I have looked at several examples including net core 2.1 Dependency injection But I don´t understand how to use the class library directly, Is it necessary to use an controller ?!
If DatabaseSettings
is accessible to the class library, there really is not much need for tightly coupling Class1
library to IOptions
, which is more framework related.
Ideally Class1
can explicitly depend on DatabaseSettings
via explicit constructor injection
public class Class1 : IConnectionOption {
private readonly DatabaseSettings test;
public Class1(DatabaseSettings settings) {
test = settings;
}
public void ReadValue() {
var r = test;
//...
}
}
then in Startup
, the dependency can be extract from configuration and registered with the DI container
public void ConfigureServices(IServiceCollection services) {
var settings = Configuration.GetSection("DatabaseSettings").Get<DatabaseSettings>();
services.AddSingleton<DatabaseSettings>(settings);
services.AddTransient<IConnectionOption, Class1>();
}
That way when ever Class1
is resolved, the container will know how to inject the DatabaseSettings
dependency.
Another option could have also been to use the factory delegate
public void ConfigureServices(IServiceCollection services) {
var settings = Configuration.GetSection("DatabaseSettings").Get<DatabaseSettings>();
services.AddTransient<IConnectionOption, Class1>(_ => new Class1(settings));
}
That way, when the IndexModel
depends on IConnectionOption
for injection.
public class IndexModel : PageModel {
private readonly IConnectionOption connectionOption;
public IndexModel(IConnectionOption iConnectionOption) {
connectionOption = iConnectionOption;
}
public void OnGet() {
connectionOption.ReadValue();
//...
}
}
the proper dependency will be injected when the page model is initialized.
You are using Dependency Injection but only halfway. This is what you are missing:
Register the service in the container (I'm going to assume a better name for Class1
):
services.AddScoped<IConnectionOption, DatabaseConnectionOption>();
Make the page receive the service:
public class IndexModel : PageModel
{
private readonly IConnectionOption _IConnectionOption;
public IndexModel(IConnectionOption iConnectionOption)
{
_IConnectionOption = iConnectionOption;
}
public void OnGet()
{
_IConnectionOption.ReadValue();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With