导航

07-001 Options 之 IConfigureOptions<TOptions>

Posted on 2015-04-02 16:02  DotNet1010  阅读(249)  评论(0)    收藏  举报

接口代码:

    public interface IConfigureOptions<in TOptions>
    {
        int Order { get; }
        void Configure(TOptions options, string name = "");
    }

 实现这个接口的有两个类:

 public class ConfigureOptions<TOptions> : IConfigureOptions<TOptions>{}
public class ConfigureFromConfigurationOptions<TOptions> : ConfigureOptions<TOptions>{}

 ConfigureOptions 的部分代码: 根据参数 name 来决定是否调用在构造函数中传入的方法。

        public ConfigureOptions([NotNull]Action<TOptions> action)
        {
            Action = action;
        }
        public string Name { get; set; } = "";
        public virtual int Order { get; set; } = OptionsConstants.DefaultOrder; // =0 
       public virtual void Configure([NotNull]TOptions options, string name = "")
        {
            // Always invoke the action if no Name was specified, otherwise only if it was the requested name
            if (string.IsNullOrEmpty(Name) || string.Equals(name, Name, StringComparison.OrdinalIgnoreCase))
            {
                Action.Invoke(options);
            }
        }

 而 ConfigureFromConfigurationOptions 继承自 ConfigureOptions:代码比较简单:

   public class ConfigureFromConfigurationOptions<TOptions> : ConfigureOptions<TOptions>
    {
        public ConfigureFromConfigurationOptions([NotNull] IConfiguration config) 
            : base(options => OptionsServices.ReadProperties(options, config))
        {
        }
    }

 OptionsServices.ReadProperties(options, config) 主要是读取配置中的属性 赋值给 options. 当然字段要一致。

代码如下:

  public static void ReadProperties(object obj, IConfiguration config)
        {
            // No convert on portable or core
#if NET45 || ASPNET50
            if (obj == null || config == null)
            {
                return;
            }
            var props = obj.GetType().GetProperties();
            foreach (var prop in props)
            {
                // Only try to set properties with public setters
                if (prop.GetSetMethod() == null)
                {
                    continue;
                }
                var configValue = config.Get(prop.Name);
                if (configValue == null)
                {
                    // Try to bind recursively
                    ReadProperties(prop.GetValue(obj), config.GetSubKey(prop.Name));
                    continue;
                }
                try
                {
                    prop.SetValue(obj, Convert.ChangeType(configValue, prop.PropertyType));
                }
                catch
                {
                    // Ignore errors
                }
            }
#endif
        }