c# 高级编程 20章449页 【依赖注入】【用选项来初始化服务】

233 阅读1分钟

如何使用选项来初始化服务:

下面这个例子中,需要传递给服务的初始化信息是 “谁打招呼”, 需要这个初始化信息的服务是 “打招呼” 这个服务

“谁打招呼”这个初始化信息,用GreetingServiceOptions来盛放, 这个class不必实现IOptions接口

“打招呼”这个服务的构造函数,现下需要传入 IOptions<GreetingServiceOptions> 类型的参数options。“打招呼”这个服务的实例,在拿到这个参数之后cache到memory里,供服务中的“打招呼”方法 使用, options.Value就是GreetingServiceOptions的实例

在注册服务的时候,需要额外调用ServiceCollection或者IServiceCollection的一些方法

  • ServiceCollection的 services.AddOptions()
  • IServiceCollection的 service.Configure(), 这个方法的参数是Action<GreetingServiceOptions> 类型的,例如 options => {options.From = "Christian"; }

示例代码:

    class Program
    {
        static void Main()
        {
            using (var container = RegisterServices())
            {
                var controller = container.GetService<HomeController>();
                string result = controller.Hello("Katharina");
                Console.WriteLine(result);
            }
        }

        static ServiceProvider RegisterServices()
        {
            var services = new ServiceCollection();
            services.AddOptions();
            services.AddGreetingService(options =>
            {
                options.From = "Christian";
            });
            services.AddTransient<HomeController>();
            return services.BuildServiceProvider();
        }
    }
    public class HomeController
    {
        private readonly IGreetingService _greetingService;
        public HomeController(IGreetingService greetingService)
        {
            _greetingService = greetingService;
        }
        public string Hello(string name) => _greetingService.Greet(name);
    }
    public class GreetingService : IGreetingService
    {
        public GreetingService(IOptions<GreetingServiceOptions> options) =>
            _from = options.Value.From;

        private readonly string _from;

        public string Greet(string name) => $"Hello, {name}! Greetings from {_from}";
    }
    
    public interface IGreetingService
    {
        string Greet(string name);
    }
    public static class GreetingServiceExtensions
    {
        public static IServiceCollection AddGreetingService(this IServiceCollection collection,
            Action<GreetingServiceOptions> setupAction)
        {
            if (collection == null) throw new ArgumentNullException(nameof(collection));
            if (setupAction == null) throw new ArgumentNullException(nameof(setupAction));

            collection.Configure(setupAction);
            return collection.AddTransient<IGreetingService, GreetingService>();
        }
    }
    public class GreetingServiceOptions
    {
        public string From { get; set; }
    }

输出:

Hello, Katharina! Greetings from Christian