ASP.NET Core 옵션 모드 소스 학습Options Ioptions(둘)

7558 단어
전언
이전 기사에서 IOptions의 등록을 소개하였는데, 이 장에서 우리는 계속 아래를 보았다
IOptions
IOptions는 하나의 인터페이스 안에 하나의Values 속성만 있고 이 인터페이스는 Options Manager를 통해 실현된다

   public interface IOptions where TOptions : class, new()
    {
        /// 
        /// The default configured  instance
        /// 
        TOptions Value { get; }
    }

OptionsManager
Options Manager는 IOptions<>와 IOptions Snapshot<>을 실현했고 내부 속성인 Options Cache를 사용하여 캐시 조작을 했다.IOptions Snapshot 인터페이스 Get(string name)을 실현하는 것은 우리의 첫 번째 장에서 지정한 Name을 가져오는 것입니다. IOptions Factory<>를 통해 TOptions 실례를 만듭니다.
    public class OptionsManager : IOptions, IOptionsSnapshot where TOptions : class, new()
    {
        private readonly IOptionsFactory _factory;
        private readonly OptionsCache _cache = new OptionsCache(); // Note: this is a private cache

        /// 
        /// Initializes a new instance with the specified options configurations.
        /// 
        /// The factory to use to create options.
        public OptionsManager(IOptionsFactory factory)
        {
            _factory = factory;
        }

        /// 
        /// The default configured  instance, equivalent to Get(Options.DefaultName).
        /// 
        public TOptions Value
        {
            get
            {
                return Get(Options.DefaultName);
            }
        }

        /// 
        /// Returns a configured  instance with the given .
        /// 
        public virtual TOptions Get(string name)
        {
            name = name ?? Options.DefaultName;

            // Store the options in our instance cache
            return _cache.GetOrAdd(name, () => _factory.Create(name));
        }
    }
    
        public interface IOptionsSnapshot : IOptions where TOptions : class, new()
    {
        /// 
        /// Returns a configured  instance with the given name.
        /// 
        TOptions Get(string name);
    }

OptionsCache
Options Cache는 스레드 보안 사전인 Concurrent Dictionary를 사용하여 메모리 캐시에 봉인되었습니다

    public class OptionsCache : IOptionsMonitorCache where TOptions : class
    {
        private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>(StringComparer.Ordinal);

        /// 
        /// Clears all options instances from the cache.
        /// 
        public void Clear() => _cache.Clear();

        /// 
        /// Gets a named options instance, or adds a new instance created with .
        /// 
        /// The name of the options instance.
        /// The func used to create the new instance.
        /// The options instance.
        public virtual TOptions GetOrAdd(string name, Func createOptions)
        {
            if (createOptions == null)
            {
                throw new ArgumentNullException(nameof(createOptions));
            }
            name = name ?? Options.DefaultName;
            return _cache.GetOrAdd(name, new Lazy(createOptions)).Value;
        }

        /// 
        /// Tries to adds a new option to the cache, will return false if the name already exists.
        /// 
        /// The name of the options instance.
        /// The options instance.
        /// Whether anything was added.
        public virtual bool TryAdd(string name, TOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            name = name ?? Options.DefaultName;
            return _cache.TryAdd(name, new Lazy(() => options));
        }

        /// 
        /// Try to remove an options instance.
        /// 
        /// The name of the options instance.
        /// Whether anything was removed.
        public virtual bool TryRemove(string name)
        {
            name = name ?? Options.DefaultName;
            return _cache.TryRemove(name, out var ignored);
        }
    }

OptionsFactory
OptionsFactory가 IOptionsFactory를 실현했습니다.Create(string name);, 한편, Options Factory 구조 함수에 IConfigure Options<>와 IPost Configure Options<>를 주입했다. 여기에 IEnumerable 유형 표지를 사용하여 여러 번 등록할 때 횟수에 따라 순차적으로 집행했다. 아래 코드에서 우리는 우리가 앞에서 말한 Configures와post Configures의 등록 선후 순서 문제를 보았다.

    public class OptionsFactory : IOptionsFactory where TOptions : class, new()
    {
        private readonly IEnumerable> _setups;
        private readonly IEnumerable> _postConfigures;
        private readonly IEnumerable> _validations;

        public OptionsFactory(IEnumerable> setups, IEnumerable> postConfigures) : this(setups, postConfigures, validations: null)
        { }

       
      
        public OptionsFactory(IEnumerable> setups, IEnumerable> postConfigures, IEnumerable> validations)
        {
            _setups = setups;
            _postConfigures = postConfigures;
            _validations = validations;
        }

       
        public TOptions Create(string name)
        {
            var options = new TOptions();
            foreach (var setup in _setups)
            {
                if (setup is IConfigureNamedOptions namedSetup)
                {
                    namedSetup.Configure(name, options);
                }
                else if (name == Options.DefaultName)
                {
                    setup.Configure(options);
                }
            }
            foreach (var post in _postConfigures)
            {
                post.PostConfigure(name, options);
            }

            if (_validations != null)
            {
                var failures = new List();
                foreach (var validate in _validations)
                {
                    var result = validate.Validate(name, options);
                    if (result.Failed)
                    {
                        failures.AddRange(result.Failures);
                    }
                }
                if (failures.Count > 0)
                {
                    throw new OptionsValidationException(name, typeof(TOptions), failures);
                }
            }

            return options;
        }
    }

좋은 웹페이지 즐겨찾기