Reputation: 1085
I've been following the official Microsoft documentation and I've tried to enchance my codebase like the following:
public class GRequestModel(IConfiguration config) => _config = config;
{
private readonly IConfiguration Configuration;
public string path { get; set; }
public string secret { get; set; }
public string response { get; set; }
public string remoteip { get; set; }
public GRequestModel(string res, string remip)
{
response = res;
remoteip = remip;
var secret = Configuration["GoogleRecaptchaV3:Secret"];
var path = Configuration["GoogleRecaptchaV3:ApiUrl"];
if (String.IsNullOrWhiteSpace(secret) || String.IsNullOrWhiteSpace(path))
{
//Invoke logger
throw new Exception(
"Invalid 'Secret' or 'Path' properties in appsettings.json. " +
"Parent: GoogleRecaptchaV3.");
}
}
}
But I keep getting a lot of errors if I do it like it's written in the documentation...
To clarify - my goal is to read the secret and API URL from appsettings.json and use this to set the values for Google's reCAPTCHA v3.
I need to do this because I want to migrate my web app to a stable version of .NET 6.
Upvotes: 0
Views: 4352
Reputation: 38777
Firstly, the syntax you have is wrong. Dependency injection should be done through the constructor (although some IoC containers provide property injection too):
public class GRequestModel
{
public string path { get; set; }
public string secret { get; set; }
public string response { get; set; }
public string remoteip { get; set; }
public GRequestModel(IConfiguration configuration, string res, string remip)
{
response = res;
remoteip = remip;
var secret = configuration["GoogleRecaptchaV3:Secret"];
var path = configuration["GoogleRecaptchaV3:ApiUrl"];
if (String.IsNullOrWhiteSpace(secret) || String.IsNullOrWhiteSpace(path))
{
//Invoke logger
throw new Exception("Invalid 'Secret' or 'Path' properties in appsettings.json. Parent: GoogleRecaptchaV3.");
}
}
}
Now we're accepting IConfiguration
in the correct place, we can address how to create this object and get IConfiguration
from the container. To do this, I'm going to create a delegate in the same GRequestModel
class:
public class GRequestModel
{
public delegate GRequestModel Factory(string res, string remip);
Then we can register this factory with the container:
services.AddTransient<GRequestModel.Factory>(serviceProvider =>
(string res, string remip) => new GRequestModel(serviceProvider.GetRequiredService<IConfiguration>(), res, remip));
Now you can inject GRequestModel.Factory
and create a GRequestModel
using it:
public class SomeOtherClass
{
public SomeOtherClass(GRequestModel.Factory grequestFactory)
{
GRequestModel grm = grequestFactory("resValue", "remipValue");
}
}
Edit: In response to your comment about it being more complicated than the documentation, that's because your use case is more complicated than the documentation examples. Specifically, you want to accept parameters res
and remip
.
Consider this example:
public class MyService
{
private readonly IConfiguration _configuration;
public MyService(IConfiguration configuration)
{
_configuration = configuration;
}
public void DoSomething(string res, string remip)
{
string configValue = _configuration["myConfigKey"];
}
}
You can register this and use this like so:
services.AddTransient<MyService>();
public class MyOtherClass
{
public MyOtherClass(MyService service)
{
service.DoSomething("resValue", "remipValue");
}
}
This is much simpler because you don't also need to inject the parameters into the constructor. It really depends on what you're trying to do as to which is the best option.
Upvotes: 2