Asp.Net Core 選項模式的三種注入方式


正文

選項模式的依賴注入共有三種接口, 分別是 IOptions<>, IOptionsSnapshot<>, IOptionsMonitor<>, 它們內部都實現了緩存,所以注入后除了第一次調用之外都是從緩存中直接取.
其中 IOptions<>, IOptionsMonitor<> 都注冊成了單例, IOptionsSnapshot<> 注冊成了作用域

services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptions<>), typeof(OptionsManager<>))); services.TryAdd(ServiceDescriptor.Scoped(typeof(IOptionsSnapshot<>), typeof(OptionsManager<>))); services.TryAdd(ServiceDescriptor.Singleton(typeof(IOptionsMonitor<>), typeof(OptionsMonitor<>)));
C#

IOptions<>

由於 IOptions<> 注冊成了單例, 整個應用程序生命周期只會實例化一次, 選項值將會在第一次調用 .Value的時候加入緩存, 之后就不會再更新了

public interface IOptions<out TOptions> where TOptions : class {     TOptions Value { get; } }
C#

OptionsManager

public class OptionsManager<TOptions> : IOptions<TOptions>, IOptionsSnapshot<TOptions> where TOptions : class {     private readonly IOptionsFactory<TOptions> _factory;     private readonly OptionsCache<TOptions> _cache = new OptionsCache<TOptions>();     public OptionsManager(IOptionsFactory<TOptions> factory)     {         _factory = factory;     }     public TOptions Value     {         get         {             return Get(Options.DefaultName);         }     }     public virtual TOptions Get(string name)     {         name = name ?? Options.DefaultName;         return _cache.GetOrAdd(name, () => _factory.Create(name));     } }
C#

IOptionsSnapshot<>

可以看到 IOptions<> 和 IOptionsSnapshot<> 的實現類都是 OptionsManager, 它們之間的區別就在於生命周期不同, IOptionsSnapshot<> 是作用域的所以它將在每一次請求重新被實例化, 選項值將會被重新獲取

public interface IOptionsSnapshot<out TOptions> : IOptions<TOptions> where TOptions : class {     TOptions Get(string name); }
C#

IOptionsMonitor<>

IOptionsMonitor<> 也是注冊成單例的, 但是它會在選項改變時接收到通知, 從而更新緩存值, 使用者也可以注冊監聽器在選項變更后,做出對應的處理

public interface IOptionsMonitor<out TOptions> {     TOptions CurrentValue { get; }     TOptions Get(string name);     IDisposable OnChange(Action<TOptions, string> listener); }
C#

總結

不需要熱更新選項的時候注入 IOptions<>, 需要熱更新和選項變更通知的注入 IOptionsMonitor<>, 僅需要熱更新的注入 IOptionsSnapshot<> 缺點是每一次請求都會重新實例化, 傳統發布不能停機的選用這個.
當然熱更新需要 reloadOnChange: True.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM