I am facing issue while configuring a service with options. In method-I GreetingService
constructor is receiving callbackAction while in method-II options.Value.CallBackAction
is passed as null in constructor.
So calling GreetingService.Greet(string)
works with Method-I while throws null exception with Method-II.
How can I pass callback delegate using Method-II
appsettings.json
{
"GreetingService": {
"From": "James"
}
}
GreetingService.cs
using Microsoft.Extensions.Options;
namespace ConsoleApp
{
public interface IGreetingService
{
void Greet(string name);
}
public class GreetingServiceOptions
{
public string? From { get; set; }
public Action<string> CallBackAction { get; set; }
}
public class GreetingService : IGreetingService
{
private readonly string? _from;
private readonly Action<string> _callBackAction;
public GreetingService(IOptions<GreetingServiceOptions> options)
{
_from = options.Value.From;
_callBackAction = options.Value.CallBackAction;
}
public void Greet(string name)
{
Console.WriteLine($"Hello, {name}! Greetings from {_from}");
_callBackAction($"Hello, {name}! Greetings from {_from}");
}
}
}
program.cs
using ConsoleApp;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
//------------------------------Method-I-----------------------------------------------
//using var host = Host.CreateDefaultBuilder()
// .ConfigureServices(services =>
// {
// services.Configure<GreetingServiceOptions>(options
// =>
// {
// options.From = "James";
// options.CallBackAction = delegate (string callBackmessage)
// {
// Console.WriteLine(callBackmessage);
// };
// });
// services.AddSingleton<IGreetingService, GreetingService>();
// }).Build();
//---------------------------------------------------------------------------------------
//------------------------------Method-II-----------------------------------------------
using var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
var configuration = context.Configuration;
var options = configuration
.GetSection("GreetingService")
.Get<GreetingServiceOptions>();
services.Configure<GreetingServiceOptions>(config =>
{
options.From = config.From;
options.CallBackAction = delegate (string callBackmessage)
{
Console.WriteLine(callBackmessage);
};
});
services.AddSingleton<IGreetingService, GreetingService>();
}).Build();
//---------------------------------------------------------------------------------------
var serviceGreeting = host.Services.GetRequiredService<IGreetingService>();
serviceGreeting.Greet("Thomas");
Console.ReadLine();
CodePudding user response:
Method 2 is configuring the wrong instance
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) => {
var configuration = context.Configuration;
//Instance extracted from configuration
GreetingServiceOptions options = configuration.GetSection("GreetingService")
.Get<GreetingServiceOptions>();
//configure IOptions from the extracted instance
services.Configure<GreetingServiceOptions>(config => {
//NOTE: the config is being modified here
config.From = options.From;
config.CallBackAction = delegate (string callBackmessage) {
Console.WriteLine(callBackmessage);
};
});
services.AddSingleton<IGreetingService, GreetingService>();
}).Build();
My belief here is that the confusion came out of naming of the variables.
Review following edit
var host = Host.CreateDefaultBuilder()
.ConfigureServices((context, services) => {
IConfiguration configuration = context.Configuration;
//Instance extracted from configuration
GreetingServiceOptions greetingsConfig = configuration.GetSection("GreetingService")
.Get<GreetingServiceOptions>();
services.Configure<GreetingServiceOptions>(options => {
options.From = greetingsConfig.From;
options.CallBackAction = delegate (string callBackmessage) {
Console.WriteLine(callBackmessage);
};
});
services.AddSingleton<IGreetingService, GreetingService>();
}).Build();
CodePudding user response:
Your property assignment should be the other way around
services.Configure<GreetingServiceOptions>(config =>
{
config.From = options.From;
config.CallBackAction = delegate (string callBackmessage)
{
Console.WriteLine(callBackmessage);
};
});