c# - 使用配置选项初始化服务未传递回调委托

我在使用选项配置服务时遇到问题。在方法-I GreetingService 中,构造函数正在接收回调动作,而在方法-II options.Value.CallBackAction 中,构造函数中作为 null 传递。

因此,调用 GreetingService.Greet(string) 可以使用 Method-I,而使用 Method-II 会引发空异常。

如何使用 Method-II 传递回调委托

应用设置.json

{
  "GreetingService": {
    "From": "James"
  }
}

问候服务.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}");
        }
    }
}

程序.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();

回答1

方法二是配置错误的实例

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();

我的信念是,混淆来自变量的命名。

查看以下编辑

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();

回答2

您的财产分配应该相反

services.Configure<GreetingServiceOptions>(config =>
{
    config.From = options.From;
    config.CallBackAction = delegate (string callBackmessage)
    {
        Console.WriteLine(callBackmessage);
    };
});

相似文章

随机推荐

最新文章