[Group 2] Enable nullable annotations for `Microsoft.Extensions.Options` (#63767)
authorMaksym Koshovyi <maximkoshevoi61@gmail.com>
Fri, 11 Feb 2022 16:34:13 +0000 (18:34 +0200)
committerGitHub <noreply@github.com>
Fri, 11 Feb 2022 16:34:13 +0000 (10:34 -0600)
* Everithing but ref

* Update ValidateOptions.cs

* Update ref

* ConfigureNamedOptions TDep is notnull

* PostConfigureOptions Tdep is notnull

* OptionsMonitor.OnChange name is notnull

* Revert non-nullable changes

* Fix invalid ref

* Failures notnull only when Failed

* FailureMessage is notnull

* Validation is nonnull

* Update OptionsValidationTests.cs

* OptionsFactory.Create name is nonnull

24 files changed:
src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.cs
src/libraries/Microsoft.Extensions.Options/ref/Microsoft.Extensions.Options.csproj
src/libraries/Microsoft.Extensions.Options/src/ConfigureNamedOptions.cs
src/libraries/Microsoft.Extensions.Options/src/ConfigureOptions.cs
src/libraries/Microsoft.Extensions.Options/src/IConfigureNamedOptions.cs
src/libraries/Microsoft.Extensions.Options/src/IOptionsChangeTokenSource.cs
src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitor.cs
src/libraries/Microsoft.Extensions.Options/src/IOptionsMonitorCache.cs
src/libraries/Microsoft.Extensions.Options/src/IOptionsSnapshot.cs
src/libraries/Microsoft.Extensions.Options/src/IPostConfigureOptions.cs
src/libraries/Microsoft.Extensions.Options/src/IValidateOptions.cs
src/libraries/Microsoft.Extensions.Options/src/Microsoft.Extensions.Options.csproj
src/libraries/Microsoft.Extensions.Options/src/OptionsBuilder.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsCache.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsServiceCollectionExtensions.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsValidationException.cs
src/libraries/Microsoft.Extensions.Options/src/OptionsWrapper.cs
src/libraries/Microsoft.Extensions.Options/src/PostConfigureOptions.cs
src/libraries/Microsoft.Extensions.Options/src/UnnamedOptionsManager.cs
src/libraries/Microsoft.Extensions.Options/src/ValidateOptions.cs
src/libraries/Microsoft.Extensions.Options/src/ValidateOptionsResult.cs
src/libraries/Microsoft.Extensions.Options/tests/Microsoft.Extensions.Options.Tests/OptionsValidationTests.cs

index c596b9d..8b3dd4b 100644 (file)
@@ -10,92 +10,92 @@ namespace Microsoft.Extensions.DependencyInjection
     {
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) { throw null; }
         public static Microsoft.Extensions.Options.OptionsBuilder<TOptions> AddOptions<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TOptions : class { throw null; }
-        public static Microsoft.Extensions.Options.OptionsBuilder<TOptions> AddOptions<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) where TOptions : class { throw null; }
+        public static Microsoft.Extensions.Options.OptionsBuilder<TOptions> AddOptions<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name) where TOptions : class { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureAll<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, object configureInstance) { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type configureType) { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] TConfigureOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) where TConfigureOptions : class { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
-        public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
+        public static Microsoft.Extensions.DependencyInjection.IServiceCollection Configure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection PostConfigureAll<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
         public static Microsoft.Extensions.DependencyInjection.IServiceCollection PostConfigure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
-        public static Microsoft.Extensions.DependencyInjection.IServiceCollection PostConfigure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
+        public static Microsoft.Extensions.DependencyInjection.IServiceCollection PostConfigure<TOptions>(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name, System.Action<TOptions> configureOptions) where TOptions : class { throw null; }
     }
 }
 namespace Microsoft.Extensions.Options
 {
     public partial class ConfigureNamedOptions<TOptions> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class
     {
-        public ConfigureNamedOptions(string name, System.Action<TOptions> action) { }
-        public System.Action<TOptions> Action { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public ConfigureNamedOptions(string? name, System.Action<TOptions>? action) { }
+        public System.Action<TOptions>? Action { get { throw null; } }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureNamedOptions<TOptions, TDep> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class where TDep : class
     {
-        public ConfigureNamedOptions(string name, TDep dependency, System.Action<TOptions, TDep> action) { }
-        public System.Action<TOptions, TDep> Action { get { throw null; } }
+        public ConfigureNamedOptions(string? name, TDep dependency, System.Action<TOptions, TDep>? action) { }
+        public System.Action<TOptions, TDep>? Action { get { throw null; } }
         public TDep Dependency { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureNamedOptions<TOptions, TDep1, TDep2> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class
     {
-        public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, System.Action<TOptions, TDep1, TDep2> action) { }
-        public System.Action<TOptions, TDep1, TDep2> Action { get { throw null; } }
+        public ConfigureNamedOptions(string? name, TDep1 dependency, TDep2 dependency2, System.Action<TOptions, TDep1, TDep2>? action) { }
+        public System.Action<TOptions, TDep1, TDep2>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureNamedOptions<TOptions, TDep1, TDep2, TDep3> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class
     {
-        public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, System.Action<TOptions, TDep1, TDep2, TDep3> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3> Action { get { throw null; } }
+        public ConfigureNamedOptions(string? name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, System.Action<TOptions, TDep1, TDep2, TDep3>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureNamedOptions<TOptions, TDep1, TDep2, TDep3, TDep4> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class where TDep4 : class
     {
-        public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4> Action { get { throw null; } }
+        public ConfigureNamedOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureNamedOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> : Microsoft.Extensions.Options.IConfigureNamedOptions<TOptions>, Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class where TDep4 : class where TDep5 : class
     {
-        public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get { throw null; } }
+        public ConfigureNamedOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
         public TDep5 Dependency5 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void Configure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void Configure(string? name, TOptions options) { }
         public void Configure(TOptions options) { }
     }
     public partial class ConfigureOptions<TOptions> : Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class
     {
-        public ConfigureOptions(System.Action<TOptions> action) { }
-        public System.Action<TOptions> Action { get { throw null; } }
+        public ConfigureOptions(System.Action<TOptions>? action) { }
+        public System.Action<TOptions>? Action { get { throw null; } }
         public virtual void Configure(TOptions options) { }
     }
     public partial interface IConfigureNamedOptions<in TOptions> : Microsoft.Extensions.Options.IConfigureOptions<TOptions> where TOptions : class
     {
-        void Configure(string name, TOptions options);
+        void Configure(string? name, TOptions options);
     }
     public partial interface IConfigureOptions<in TOptions> where TOptions : class
     {
@@ -103,7 +103,7 @@ namespace Microsoft.Extensions.Options
     }
     public partial interface IOptionsChangeTokenSource<out TOptions>
     {
-        string Name { get; }
+        string? Name { get; }
         Microsoft.Extensions.Primitives.IChangeToken GetChangeToken();
     }
     public partial interface IOptionsFactory<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> where TOptions : class
@@ -113,19 +113,19 @@ namespace Microsoft.Extensions.Options
     public partial interface IOptionsMonitorCache<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> where TOptions : class
     {
         void Clear();
-        TOptions GetOrAdd(string name, System.Func<TOptions> createOptions);
-        bool TryAdd(string name, TOptions options);
-        bool TryRemove(string name);
+        TOptions GetOrAdd(string? name, System.Func<TOptions> createOptions);
+        bool TryAdd(string? name, TOptions options);
+        bool TryRemove(string? name);
     }
     public partial interface IOptionsMonitor<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions>
     {
         TOptions CurrentValue { get; }
-        TOptions Get(string name);
-        System.IDisposable OnChange(System.Action<TOptions, string> listener);
+        TOptions Get(string? name);
+        System.IDisposable OnChange(System.Action<TOptions, string?> listener);
     }
     public partial interface IOptionsSnapshot<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions> : Microsoft.Extensions.Options.IOptions<TOptions> where TOptions : class
     {
-        TOptions Get(string name);
+        TOptions Get(string? name);
     }
     public partial interface IOptions<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] out TOptions> where TOptions : class
     {
@@ -133,11 +133,11 @@ namespace Microsoft.Extensions.Options
     }
     public partial interface IPostConfigureOptions<in TOptions> where TOptions : class
     {
-        void PostConfigure(string name, TOptions options);
+        void PostConfigure(string? name, TOptions options);
     }
     public partial interface IValidateOptions<TOptions> where TOptions : class
     {
-        Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options);
+        Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options);
     }
     public static partial class Options
     {
@@ -146,7 +146,7 @@ namespace Microsoft.Extensions.Options
     }
     public partial class OptionsBuilder<TOptions> where TOptions : class
     {
-        public OptionsBuilder(Microsoft.Extensions.DependencyInjection.IServiceCollection services, string name) { }
+        public OptionsBuilder(Microsoft.Extensions.DependencyInjection.IServiceCollection services, string? name) { }
         public string Name { get { throw null; } }
         public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { get { throw null; } }
         public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Configure(System.Action<TOptions> configureOptions) { throw null; }
@@ -163,24 +163,24 @@ namespace Microsoft.Extensions.Options
         public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> PostConfigure<TDep1, TDep2, TDep3, TDep4, TDep5>(System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> configureOptions) where TDep1 : class where TDep2 : class where TDep3 : class where TDep4 : class where TDep5 : class { throw null; }
         public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate(System.Func<TOptions, bool> validation) { throw null; }
         public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate(System.Func<TOptions, bool> validation, string failureMessage) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep>(System.Func<TOptions, TDep, bool> validation) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep>(System.Func<TOptions, TDep, bool> validation, string failureMessage) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2>(System.Func<TOptions, TDep1, TDep2, bool> validation) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2>(System.Func<TOptions, TDep1, TDep2, bool> validation, string failureMessage) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation, string failureMessage) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation, string failureMessage) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation) { throw null; }
-        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation, string failureMessage) { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep>(System.Func<TOptions, TDep, bool> validation) where TDep : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep>(System.Func<TOptions, TDep, bool> validation, string failureMessage) where TDep : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2>(System.Func<TOptions, TDep1, TDep2, bool> validation) where TDep1 : notnull where TDep2 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2>(System.Func<TOptions, TDep1, TDep2, bool> validation, string failureMessage) where TDep1 : notnull where TDep2 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation, string failureMessage) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull where TDep4 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation, string failureMessage) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull where TDep4 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull where TDep4 : notnull where TDep5 : notnull { throw null; }
+        public virtual Microsoft.Extensions.Options.OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation, string failureMessage) where TDep1 : notnull where TDep2 : notnull where TDep3 : notnull where TDep4 : notnull where TDep5 : notnull { throw null; }
     }
     public partial class OptionsCache<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptionsMonitorCache<TOptions> where TOptions : class
     {
         public OptionsCache() { }
         public void Clear() { }
-        public virtual TOptions GetOrAdd(string name, System.Func<TOptions> createOptions) { throw null; }
-        public virtual bool TryAdd(string name, TOptions options) { throw null; }
-        public virtual bool TryRemove(string name) { throw null; }
+        public virtual TOptions GetOrAdd(string? name, System.Func<TOptions> createOptions) { throw null; }
+        public virtual bool TryAdd(string? name, TOptions options) { throw null; }
+        public virtual bool TryRemove(string? name) { throw null; }
     }
     public partial class OptionsFactory<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : Microsoft.Extensions.Options.IOptionsFactory<TOptions> where TOptions : class
     {
@@ -193,7 +193,7 @@ namespace Microsoft.Extensions.Options
     {
         public OptionsManager(Microsoft.Extensions.Options.IOptionsFactory<TOptions> factory) { }
         public TOptions Value { get { throw null; } }
-        public virtual TOptions Get(string name) { throw null; }
+        public virtual TOptions Get(string? name) { throw null; }
     }
     public static partial class OptionsMonitorExtensions
     {
@@ -204,12 +204,12 @@ namespace Microsoft.Extensions.Options
         public OptionsMonitor(Microsoft.Extensions.Options.IOptionsFactory<TOptions> factory, System.Collections.Generic.IEnumerable<Microsoft.Extensions.Options.IOptionsChangeTokenSource<TOptions>> sources, Microsoft.Extensions.Options.IOptionsMonitorCache<TOptions> cache) { }
         public TOptions CurrentValue { get { throw null; } }
         public void Dispose() { }
-        public virtual TOptions Get(string name) { throw null; }
+        public virtual TOptions Get(string? name) { throw null; }
         public System.IDisposable OnChange(System.Action<TOptions, string> listener) { throw null; }
     }
     public partial class OptionsValidationException : System.Exception
     {
-        public OptionsValidationException(string optionsName, System.Type optionsType, System.Collections.Generic.IEnumerable<string> failureMessages) { }
+        public OptionsValidationException(string optionsName, System.Type optionsType, System.Collections.Generic.IEnumerable<string>? failureMessages) { }
         public System.Collections.Generic.IEnumerable<string> Failures { get { throw null; } }
         public override string Message { get { throw null; } }
         public string OptionsName { get { throw null; } }
@@ -222,64 +222,64 @@ namespace Microsoft.Extensions.Options
     }
     public partial class PostConfigureOptions<TOptions> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class
     {
-        public PostConfigureOptions(string name, System.Action<TOptions> action) { }
-        public System.Action<TOptions> Action { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public PostConfigureOptions(string? name, System.Action<TOptions>? action) { }
+        public System.Action<TOptions>? Action { get { throw null; } }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
     }
     public partial class PostConfigureOptions<TOptions, TDep> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class where TDep : class
     {
-        public PostConfigureOptions(string name, TDep dependency, System.Action<TOptions, TDep> action) { }
-        public System.Action<TOptions, TDep> Action { get { throw null; } }
+        public PostConfigureOptions(string? name, TDep dependency, System.Action<TOptions, TDep>? action) { }
+        public System.Action<TOptions, TDep>? Action { get { throw null; } }
         public TDep Dependency { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
         public void PostConfigure(TOptions options) { }
     }
     public partial class PostConfigureOptions<TOptions, TDep1, TDep2> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class
     {
-        public PostConfigureOptions(string name, TDep1 dependency, TDep2 dependency2, System.Action<TOptions, TDep1, TDep2> action) { }
-        public System.Action<TOptions, TDep1, TDep2> Action { get { throw null; } }
+        public PostConfigureOptions(string? name, TDep1 dependency, TDep2 dependency2, System.Action<TOptions, TDep1, TDep2>? action) { }
+        public System.Action<TOptions, TDep1, TDep2>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
         public void PostConfigure(TOptions options) { }
     }
     public partial class PostConfigureOptions<TOptions, TDep1, TDep2, TDep3> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class
     {
-        public PostConfigureOptions(string name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, System.Action<TOptions, TDep1, TDep2, TDep3> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3> Action { get { throw null; } }
+        public PostConfigureOptions(string? name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, System.Action<TOptions, TDep1, TDep2, TDep3>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
         public void PostConfigure(TOptions options) { }
     }
     public partial class PostConfigureOptions<TOptions, TDep1, TDep2, TDep3, TDep4> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class where TDep4 : class
     {
-        public PostConfigureOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4> Action { get { throw null; } }
+        public PostConfigureOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
         public void PostConfigure(TOptions options) { }
     }
     public partial class PostConfigureOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> : Microsoft.Extensions.Options.IPostConfigureOptions<TOptions> where TOptions : class where TDep1 : class where TDep2 : class where TDep3 : class where TDep4 : class where TDep5 : class
     {
-        public PostConfigureOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> action) { }
-        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get { throw null; } }
+        public PostConfigureOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? action) { }
+        public System.Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? Action { get { throw null; } }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
         public TDep5 Dependency5 { get { throw null; } }
-        public string Name { get { throw null; } }
-        public virtual void PostConfigure(string name, TOptions options) { }
+        public string? Name { get { throw null; } }
+        public virtual void PostConfigure(string? name, TOptions options) { }
         public void PostConfigure(TOptions options) { }
     }
     public partial class ValidateOptionsResult
@@ -287,9 +287,11 @@ namespace Microsoft.Extensions.Options
         public static readonly Microsoft.Extensions.Options.ValidateOptionsResult Skip;
         public static readonly Microsoft.Extensions.Options.ValidateOptionsResult Success;
         public ValidateOptionsResult() { }
+        [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, nameof(Failures))]
+        [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, nameof(FailureMessage))]
         public bool Failed { get { throw null; } protected set { } }
-        public string FailureMessage { get { throw null; } protected set { } }
-        public System.Collections.Generic.IEnumerable<string> Failures { get { throw null; } protected set { } }
+        public string? FailureMessage { get { throw null; } protected set { } }
+        public System.Collections.Generic.IEnumerable<string>? Failures { get { throw null; } protected set { } }
         public bool Skipped { get { throw null; } protected set { } }
         public bool Succeeded { get { throw null; } protected set { } }
         public static Microsoft.Extensions.Options.ValidateOptionsResult Fail(System.Collections.Generic.IEnumerable<string> failures) { throw null; }
@@ -297,65 +299,65 @@ namespace Microsoft.Extensions.Options
     }
     public partial class ValidateOptions<TOptions> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, System.Func<TOptions, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, System.Func<TOptions, bool> validation, string failureMessage) { }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
     public partial class ValidateOptions<TOptions, TDep> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, TDep dependency, System.Func<TOptions, TDep, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, TDep dependency, System.Func<TOptions, TDep, bool> validation, string failureMessage) { }
         public TDep Dependency { get { throw null; } }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, TDep, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
     public partial class ValidateOptions<TOptions, TDep1, TDep2> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, System.Func<TOptions, TDep1, TDep2, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, System.Func<TOptions, TDep1, TDep2, bool> validation, string failureMessage) { }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, TDep1, TDep2, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
     public partial class ValidateOptions<TOptions, TDep1, TDep2, TDep3> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, System.Func<TOptions, TDep1, TDep2, TDep3, bool> validation, string failureMessage) { }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, TDep1, TDep2, TDep3, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
     public partial class ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation, string failureMessage) { }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
     public partial class ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> : Microsoft.Extensions.Options.IValidateOptions<TOptions> where TOptions : class
     {
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation, string failureMessage) { }
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation, string failureMessage) { }
         public TDep1 Dependency1 { get { throw null; } }
         public TDep2 Dependency2 { get { throw null; } }
         public TDep3 Dependency3 { get { throw null; } }
         public TDep4 Dependency4 { get { throw null; } }
         public TDep5 Dependency5 { get { throw null; } }
         public string FailureMessage { get { throw null; } }
-        public string Name { get { throw null; } }
+        public string? Name { get { throw null; } }
         public System.Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> Validation { get { throw null; } }
-        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string name, TOptions options) { throw null; }
+        public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
     }
 }
index 2d11420..4ba4e7d 100644 (file)
@@ -1,6 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>
index cf4bc8c..a3f9409 100644 (file)
@@ -16,7 +16,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, Action<TOptions> action)
+        public ConfigureNamedOptions(string? name, Action<TOptions>? action)
         {
             Name = name;
             Action = action;
@@ -25,19 +25,19 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions> Action { get; }
+        public Action<TOptions>? Action { get; }
 
         /// <summary>
         /// Invokes the registered configure <see cref="Action"/> if the <paramref name="name"/> matches.
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -68,7 +68,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options.</param>
         /// <param name="dependency">A dependency.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, TDep dependency, Action<TOptions, TDep> action)
+        public ConfigureNamedOptions(string? name, TDep dependency, Action<TOptions, TDep>? action)
         {
             Name = name;
             Action = action;
@@ -78,12 +78,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep> Action { get; }
+        public Action<TOptions, TDep>? Action { get; }
 
         /// <summary>
         /// The dependency.
@@ -95,7 +95,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -129,7 +129,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency">A dependency.</param>
         /// <param name="dependency2">A second dependency.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, Action<TOptions, TDep1, TDep2> action)
+        public ConfigureNamedOptions(string? name, TDep1 dependency, TDep2 dependency2, Action<TOptions, TDep1, TDep2>? action)
         {
             Name = name;
             Action = action;
@@ -140,12 +140,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2> Action { get; }
+        public Action<TOptions, TDep1, TDep2>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -162,7 +162,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -199,7 +199,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency2">A second dependency.</param>
         /// <param name="dependency3">A third dependency.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, Action<TOptions, TDep1, TDep2, TDep3> action)
+        public ConfigureNamedOptions(string? name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, Action<TOptions, TDep1, TDep2, TDep3>? action)
         {
             Name = name;
             Action = action;
@@ -211,12 +211,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -238,7 +238,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -278,7 +278,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency3">A third dependency.</param>
         /// <param name="dependency4">A fourth dependency.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Action<TOptions, TDep1, TDep2, TDep3, TDep4> action)
+        public ConfigureNamedOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Action<TOptions, TDep1, TDep2, TDep3, TDep4>? action)
         {
             Name = name;
             Action = action;
@@ -291,12 +291,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3, TDep4> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3, TDep4>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -323,7 +323,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -366,7 +366,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency4">A fourth dependency.</param>
         /// <param name="dependency5">A fifth dependency.</param>
         /// <param name="action">The action to register.</param>
-        public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> action)
+        public ConfigureNamedOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? action)
         {
             Name = name;
             Action = action;
@@ -380,12 +380,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -417,7 +417,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        public virtual void Configure(string name, TOptions options!!)
+        public virtual void Configure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
index fa9c3b8..556f45b 100644 (file)
@@ -15,7 +15,7 @@ namespace Microsoft.Extensions.Options
         /// Constructor.
         /// </summary>
         /// <param name="action">The action to register.</param>
-        public ConfigureOptions(Action<TOptions> action)
+        public ConfigureOptions(Action<TOptions>? action)
         {
             Action = action;
         }
@@ -23,7 +23,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions> Action { get; }
+        public Action<TOptions>? Action { get; }
 
         /// <summary>
         /// Invokes the registered configure <see cref="Action"/>.
index 7cb70f3..8dfef1e 100644 (file)
@@ -14,6 +14,6 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configure.</param>
-        void Configure(string name, TOptions options);
+        void Configure(string? name, TOptions options);
     }
 }
index dd7ec5b..d290a04 100644 (file)
@@ -20,6 +20,6 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The name of the option instance being changed.
         /// </summary>
-        string Name { get; }
+        string? Name { get; }
     }
 }
index 10c51cb..a3696fb 100644 (file)
@@ -20,13 +20,13 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// Returns a configured <typeparamref name="TOptions"/> instance with the given name.
         /// </summary>
-        TOptions Get(string name);
+        TOptions Get(string? name);
 
         /// <summary>
         /// Registers a listener to be called whenever a named <typeparamref name="TOptions"/> changes.
         /// </summary>
         /// <param name="listener">The action to be invoked when <typeparamref name="TOptions"/> has changed.</param>
         /// <returns>An <see cref="IDisposable"/> which should be disposed to stop listening for changes.</returns>
-        IDisposable OnChange(Action<TOptions, string> listener);
+        IDisposable OnChange(Action<TOptions, string?> listener);
     }
 }
index f06062d..ae924ad 100644 (file)
@@ -19,7 +19,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance.</param>
         /// <param name="createOptions">The func used to create the new instance.</param>
         /// <returns>The options instance.</returns>
-        TOptions GetOrAdd(string name, Func<TOptions> createOptions);
+        TOptions GetOrAdd(string? name, Func<TOptions> createOptions);
 
         /// <summary>
         /// Tries to adds a new option to the cache, will return false if the name already exists.
@@ -27,14 +27,14 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>Whether anything was added.</returns>
-        bool TryAdd(string name, TOptions options);
+        bool TryAdd(string? name, TOptions options);
 
         /// <summary>
         /// Try to remove an options instance.
         /// </summary>
         /// <param name="name">The name of the options instance.</param>
         /// <returns>Whether anything was removed.</returns>
-        bool TryRemove(string name);
+        bool TryRemove(string? name);
 
         /// <summary>
         /// Clears all options instances from the cache.
index d29a381..c0afce9 100644 (file)
@@ -16,6 +16,6 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// Returns a configured <typeparamref name="TOptions"/> instance with the given name.
         /// </summary>
-        TOptions Get(string name);
+        TOptions Get(string? name);
     }
 }
index f0f46cb..5b92895 100644 (file)
@@ -15,6 +15,6 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        void PostConfigure(string name, TOptions options);
+        void PostConfigure(string? name, TOptions options);
     }
 }
index 6022b30..cd114ee 100644 (file)
@@ -15,6 +15,6 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        ValidateOptionsResult Validate(string name, TOptions options);
+        ValidateOptionsResult Validate(string? name, TOptions options);
     }
 }
index 9ed0d47..f593699 100644 (file)
@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.1;netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
+    <Nullable>enable</Nullable>
     <EnableDefaultItems>true</EnableDefaultItems>
     <!-- Use targeting pack references instead of granular ones in the project file. -->
     <DisableImplicitAssemblyReferences>false</DisableImplicitAssemblyReferences>
index a1baf74..5819ee0 100644 (file)
@@ -29,7 +29,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="services">The <see cref="IServiceCollection"/> for the options being configured.</param>
         /// <param name="name">The default name of the <typeparamref name="TOptions"/> instance, if null <see cref="Options.DefaultName"/> is used.</param>
-        public OptionsBuilder(IServiceCollection services!!, string name)
+        public OptionsBuilder(IServiceCollection services!!, string? name)
         {
             Services = services;
             Name = name ?? Options.DefaultName;
@@ -310,7 +310,7 @@ namespace Microsoft.Extensions.Options
         /// <typeparam name="TDep">The dependency used by the validation function.</typeparam>
         /// <param name="validation">The validation function.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
-        public virtual OptionsBuilder<TOptions> Validate<TDep>(Func<TOptions, TDep, bool> validation)
+        public virtual OptionsBuilder<TOptions> Validate<TDep>(Func<TOptions, TDep, bool> validation) where TDep : notnull
             => Validate(validation: validation, failureMessage: DefaultValidationFailureMessage);
 
         /// <summary>
@@ -320,7 +320,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="validation">The validation function.</param>
         /// <param name="failureMessage">The failure message to use when validation fails.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
-        public virtual OptionsBuilder<TOptions> Validate<TDep>(Func<TOptions, TDep, bool> validation!!, string failureMessage)
+        public virtual OptionsBuilder<TOptions> Validate<TDep>(Func<TOptions, TDep, bool> validation!!, string failureMessage) where TDep : notnull
         {
             Services.AddTransient<IValidateOptions<TOptions>>(sp =>
                 new ValidateOptions<TOptions, TDep>(Name, sp.GetRequiredService<TDep>(), validation, failureMessage));
@@ -335,6 +335,8 @@ namespace Microsoft.Extensions.Options
         /// <param name="validation">The validation function.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2>(Func<TOptions, TDep1, TDep2, bool> validation)
+            where TDep1 : notnull
+            where TDep2 : notnull
             => Validate(validation: validation, failureMessage: DefaultValidationFailureMessage);
 
         /// <summary>
@@ -346,6 +348,8 @@ namespace Microsoft.Extensions.Options
         /// <param name="failureMessage">The failure message to use when validation fails.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2>(Func<TOptions, TDep1, TDep2, bool> validation!!, string failureMessage)
+            where TDep1 : notnull
+            where TDep2 : notnull
         {
             Services.AddTransient<IValidateOptions<TOptions>>(sp =>
                 new ValidateOptions<TOptions, TDep1, TDep2>(Name,
@@ -365,6 +369,9 @@ namespace Microsoft.Extensions.Options
         /// <param name="validation">The validation function.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(Func<TOptions, TDep1, TDep2, TDep3, bool> validation)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
             => Validate(validation: validation, failureMessage: DefaultValidationFailureMessage);
 
         /// <summary>
@@ -377,6 +384,9 @@ namespace Microsoft.Extensions.Options
         /// <param name="failureMessage">The failure message to use when validation fails.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3>(Func<TOptions, TDep1, TDep2, TDep3, bool> validation!!, string failureMessage)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
         {
             Services.AddTransient<IValidateOptions<TOptions>>(sp =>
                 new ValidateOptions<TOptions, TDep1, TDep2, TDep3>(Name,
@@ -398,6 +408,10 @@ namespace Microsoft.Extensions.Options
         /// <param name="validation">The validation function.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
+            where TDep4 : notnull
             => Validate(validation: validation, failureMessage: DefaultValidationFailureMessage);
 
         /// <summary>
@@ -411,6 +425,10 @@ namespace Microsoft.Extensions.Options
         /// <param name="failureMessage">The failure message to use when validation fails.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4>(Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation!!, string failureMessage)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
+            where TDep4 : notnull
         {
             Services.AddTransient<IValidateOptions<TOptions>>(sp =>
                 new ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4>(Name,
@@ -434,6 +452,11 @@ namespace Microsoft.Extensions.Options
         /// <param name="validation">The validation function.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
+            where TDep4 : notnull
+            where TDep5 : notnull
             => Validate(validation: validation, failureMessage: DefaultValidationFailureMessage);
 
         /// <summary>
@@ -448,6 +471,11 @@ namespace Microsoft.Extensions.Options
         /// <param name="failureMessage">The failure message to use when validation fails.</param>
         /// <returns>The current <see cref="OptionsBuilder{TOptions}"/>.</returns>
         public virtual OptionsBuilder<TOptions> Validate<TDep1, TDep2, TDep3, TDep4, TDep5>(Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation!!, string failureMessage)
+            where TDep1 : notnull
+            where TDep2 : notnull
+            where TDep3 : notnull
+            where TDep4 : notnull
+            where TDep5 : notnull
         {
             Services.AddTransient<IValidateOptions<TOptions>>(sp =>
                 new ValidateOptions<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>(Name,
index f431291..869fd75 100644 (file)
@@ -28,10 +28,10 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance.</param>
         /// <param name="createOptions">The func used to create the new instance.</param>
         /// <returns>The options instance.</returns>
-        public virtual TOptions GetOrAdd(string name, Func<TOptions> createOptions!!)
+        public virtual TOptions GetOrAdd(string? name, Func<TOptions> createOptions!!)
         {
             name ??= Options.DefaultName;
-            Lazy<TOptions> value;
+            Lazy<TOptions>? value;
 
 #if NETSTANDARD2_1
             value = _cache.GetOrAdd(name, static (name, createOptions) => new Lazy<TOptions>(createOptions), createOptions);
@@ -51,9 +51,9 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>true if the options were retrieved; otherwise, false.</returns>
-        internal bool TryGetValue(string name, out TOptions options)
+        internal bool TryGetValue(string? name, [MaybeNullWhen(false)] out TOptions options)
         {
-            if (_cache.TryGetValue(name ?? Options.DefaultName, out Lazy<TOptions> lazy))
+            if (_cache.TryGetValue(name ?? Options.DefaultName, out Lazy<TOptions>? lazy))
             {
                 options = lazy.Value;
                 return true;
@@ -69,7 +69,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>Whether anything was added.</returns>
-        public virtual bool TryAdd(string name, TOptions options!!)
+        public virtual bool TryAdd(string? name, TOptions options!!)
         {
             return _cache.TryAdd(name ?? Options.DefaultName, new Lazy<TOptions>(
 #if !NETSTANDARD2_1
@@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance.</param>
         /// <returns>Whether anything was removed.</returns>
-        public virtual bool TryRemove(string name) =>
+        public virtual bool TryRemove(string? name) =>
             _cache.TryRemove(name ?? Options.DefaultName, out _);
     }
 }
index 83fc0ec..f5a7442 100644 (file)
@@ -34,11 +34,11 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// Returns a configured <typeparamref name="TOptions"/> instance with the given <paramref name="name"/>.
         /// </summary>
-        public virtual TOptions Get(string name)
+        public virtual TOptions Get(string? name)
         {
             name = name ?? Options.DefaultName;
 
-            if (!_cache.TryGetValue(name, out TOptions options))
+            if (!_cache.TryGetValue(name, out TOptions? options))
             {
                 // Store the options in our instance cache. Avoid closure on fast path by storing state into scoped locals.
                 IOptionsFactory<TOptions> localFactory = _factory;
index 2b7fbf0..d75bc70 100644 (file)
@@ -20,7 +20,7 @@ namespace Microsoft.Extensions.Options
         private readonly IOptionsMonitorCache<TOptions> _cache;
         private readonly IOptionsFactory<TOptions> _factory;
         private readonly List<IDisposable> _registrations = new List<IDisposable>();
-        internal event Action<TOptions, string> _onChange;
+        internal event Action<TOptions, string>? _onChange;
 
         /// <summary>
         /// Constructor.
@@ -61,7 +61,7 @@ namespace Microsoft.Extensions.Options
             }
         }
 
-        private void InvokeChanged(string name)
+        private void InvokeChanged(string? name)
         {
             name = name ?? Options.DefaultName;
             _cache.TryRemove(name);
@@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// Returns a configured <typeparamref name="TOptions"/> instance with the given <paramref name="name"/>.
         /// </summary>
-        public virtual TOptions Get(string name)
+        public virtual TOptions Get(string? name)
         {
             name = name ?? Options.DefaultName;
             return _cache.GetOrAdd(name, () => _factory.Create(name));
index eff6706..73e3c43 100644 (file)
@@ -49,7 +49,7 @@ namespace Microsoft.Extensions.DependencyInjection
         /// <param name="name">The name of the options instance.</param>
         /// <param name="configureOptions">The action used to configure the options.</param>
         /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
-        public static IServiceCollection Configure<TOptions>(this IServiceCollection services!!, string name, Action<TOptions> configureOptions!!)
+        public static IServiceCollection Configure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
             where TOptions : class
         {
             services.AddOptions();
@@ -87,7 +87,7 @@ namespace Microsoft.Extensions.DependencyInjection
         /// <param name="name">The name of the options instance.</param>
         /// <param name="configureOptions">The action used to configure the options.</param>
         /// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
-        public static IServiceCollection PostConfigure<TOptions>(this IServiceCollection services!!, string name, Action<TOptions> configureOptions!!)
+        public static IServiceCollection PostConfigure<TOptions>(this IServiceCollection services!!, string? name, Action<TOptions> configureOptions!!)
             where TOptions : class
         {
             services.AddOptions();
@@ -225,7 +225,7 @@ namespace Microsoft.Extensions.DependencyInjection
         /// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
         /// <param name="name">The name of the options instance.</param>
         /// <returns>The <see cref="OptionsBuilder{TOptions}"/> so that configure calls can be chained in it.</returns>
-        public static OptionsBuilder<TOptions> AddOptions<TOptions>(this IServiceCollection services!!, string name)
+        public static OptionsBuilder<TOptions> AddOptions<TOptions>(this IServiceCollection services!!, string? name)
             where TOptions : class
         {
             services.AddOptions();
index b20e185..f5b4bcf 100644 (file)
@@ -17,7 +17,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="optionsName">The name of the options instance that failed.</param>
         /// <param name="optionsType">The options type that failed.</param>
         /// <param name="failureMessages">The validation failure messages.</param>
-        public OptionsValidationException(string optionsName!!, Type optionsType!!, IEnumerable<string> failureMessages)
+        public OptionsValidationException(string optionsName!!, Type optionsType!!, IEnumerable<string>? failureMessages)
         {
             Failures = failureMessages ?? new List<string>();
             OptionsType = optionsType;
index cdc2958..4de276d 100644 (file)
@@ -14,7 +14,7 @@ namespace Microsoft.Extensions.Options
         where TOptions : class
     {
         /// <summary>
-        /// Intializes the wrapper with the options instance to return.
+        /// Initializes the wrapper with the options instance to return.
         /// </summary>
         /// <param name="options">The options instance to return.</param>
         public OptionsWrapper(TOptions options)
index 5049ef1..138220a 100644 (file)
@@ -16,7 +16,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, Action<TOptions> action)
+        public PostConfigureOptions(string? name, Action<TOptions>? action)
         {
             Name = name;
             Action = action;
@@ -25,19 +25,19 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The initialization action.
         /// </summary>
-        public Action<TOptions> Action { get; }
+        public Action<TOptions>? Action { get; }
 
         /// <summary>
         /// Invokes the registered initialization <see cref="Action"/> if the <paramref name="name"/> matches.
         /// </summary>
         /// <param name="name">The name of the action to invoke.</param>
         /// <param name="options">The options to use in initialization.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to initialize all named options.
             if (Name == null || name == Name)
@@ -62,7 +62,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options.</param>
         /// <param name="dependency">A dependency.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, TDep dependency, Action<TOptions, TDep> action)
+        public PostConfigureOptions(string? name, TDep dependency, Action<TOptions, TDep>? action)
         {
             Name = name;
             Action = action;
@@ -72,12 +72,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep> Action { get; }
+        public Action<TOptions, TDep>? Action { get; }
 
         /// <summary>
         /// The dependency.
@@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -123,7 +123,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency">A dependency.</param>
         /// <param name="dependency2">A second dependency.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, TDep1 dependency, TDep2 dependency2, Action<TOptions, TDep1, TDep2> action)
+        public PostConfigureOptions(string? name, TDep1 dependency, TDep2 dependency2, Action<TOptions, TDep1, TDep2>? action)
         {
             Name = name;
             Action = action;
@@ -134,12 +134,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2> Action { get; }
+        public Action<TOptions, TDep1, TDep2>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -156,7 +156,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -193,7 +193,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency2">A second dependency.</param>
         /// <param name="dependency3">A third dependency.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, Action<TOptions, TDep1, TDep2, TDep3> action)
+        public PostConfigureOptions(string? name, TDep1 dependency, TDep2 dependency2, TDep3 dependency3, Action<TOptions, TDep1, TDep2, TDep3>? action)
         {
             Name = name;
             Action = action;
@@ -205,12 +205,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -232,7 +232,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -272,7 +272,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency3">A third dependency.</param>
         /// <param name="dependency4">A fourth dependency.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Action<TOptions, TDep1, TDep2, TDep3, TDep4> action)
+        public PostConfigureOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Action<TOptions, TDep1, TDep2, TDep3, TDep4>? action)
         {
             Name = name;
             Action = action;
@@ -285,12 +285,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3, TDep4> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3, TDep4>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -317,7 +317,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
@@ -360,7 +360,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency4">A fourth dependency.</param>
         /// <param name="dependency5">A fifth dependency.</param>
         /// <param name="action">The action to register.</param>
-        public PostConfigureOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> action)
+        public PostConfigureOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? action)
         {
             Name = name;
             Action = action;
@@ -374,12 +374,12 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The configuration action.
         /// </summary>
-        public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get; }
+        public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5>? Action { get; }
 
         /// <summary>
         /// The first dependency.
@@ -411,7 +411,7 @@ namespace Microsoft.Extensions.Options
         /// </summary>
         /// <param name="name">The name of the options instance being configured.</param>
         /// <param name="options">The options instance to configured.</param>
-        public virtual void PostConfigure(string name, TOptions options!!)
+        public virtual void PostConfigure(string? name, TOptions options!!)
         {
             // Null name is used to configure all named options.
             if (Name == null || name == Name)
index 93dafb7..27f6d6e 100644 (file)
@@ -11,8 +11,8 @@ namespace Microsoft.Extensions.Options
         where TOptions : class
     {
         private readonly IOptionsFactory<TOptions> _factory;
-        private volatile object _syncObj;
-        private volatile TOptions _value;
+        private volatile object? _syncObj;
+        private volatile TOptions? _value;
 
         public UnnamedOptionsManager(IOptionsFactory<TOptions> factory) => _factory = factory;
 
index b70b783..de083ed 100644 (file)
@@ -17,7 +17,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">Options name.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, Func<TOptions, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, Func<TOptions, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -27,7 +27,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -45,12 +45,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options)).Value)
+                if (Validation.Invoke(options))
                 {
                     return ValidateOptionsResult.Success;
                 }
@@ -65,7 +65,7 @@ namespace Microsoft.Extensions.Options
     /// <summary>
     /// Implementation of <see cref="IValidateOptions{TOptions}"/>
     /// </summary>
-        /// <typeparam name="TOptions">The options type to validate.</typeparam>
+    /// <typeparam name="TOptions">The options type to validate.</typeparam>
     /// <typeparam name="TDep">Dependency type.</typeparam>
     public class ValidateOptions<TOptions, TDep> : IValidateOptions<TOptions> where TOptions : class
     {
@@ -76,7 +76,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency">The dependency.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, TDep dependency, Func<TOptions, TDep, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, TDep dependency, Func<TOptions, TDep, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -87,7 +87,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -110,12 +110,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options, Dependency)).Value)
+                if (Validation.Invoke(options, Dependency))
                 {
                     return ValidateOptionsResult.Success;
                 }
@@ -130,7 +130,7 @@ namespace Microsoft.Extensions.Options
     /// <summary>
     /// Implementation of <see cref="IValidateOptions{TOptions}"/>
     /// </summary>
-        /// <typeparam name="TOptions">The options type to validate.</typeparam>
+    /// <typeparam name="TOptions">The options type to validate.</typeparam>
     /// <typeparam name="TDep1">First dependency type.</typeparam>
     /// <typeparam name="TDep2">Second dependency type.</typeparam>
     public class ValidateOptions<TOptions, TDep1, TDep2> : IValidateOptions<TOptions> where TOptions : class
@@ -143,7 +143,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency2">The second dependency.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, Func<TOptions, TDep1, TDep2, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, Func<TOptions, TDep1, TDep2, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -155,7 +155,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -183,12 +183,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options, Dependency1, Dependency2)).Value)
+                if (Validation.Invoke(options, Dependency1, Dependency2))
                 {
                     return ValidateOptionsResult.Success;
                 }
@@ -203,7 +203,7 @@ namespace Microsoft.Extensions.Options
     /// <summary>
     /// Implementation of <see cref="IValidateOptions{TOptions}"/>
     /// </summary>
-        /// <typeparam name="TOptions">The options type to validate.</typeparam>
+    /// <typeparam name="TOptions">The options type to validate.</typeparam>
     /// <typeparam name="TDep1">First dependency type.</typeparam>
     /// <typeparam name="TDep2">Second dependency type.</typeparam>
     /// <typeparam name="TDep3">Third dependency type.</typeparam>
@@ -218,7 +218,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency3">The third dependency.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, Func<TOptions, TDep1, TDep2, TDep3, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, Func<TOptions, TDep1, TDep2, TDep3, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -231,7 +231,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -264,12 +264,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options, Dependency1, Dependency2, Dependency3)).Value)
+                if (Validation.Invoke(options, Dependency1, Dependency2, Dependency3))
                 {
                     return ValidateOptionsResult.Success;
                 }
@@ -284,7 +284,7 @@ namespace Microsoft.Extensions.Options
     /// <summary>
     /// Implementation of <see cref="IValidateOptions{TOptions}"/>
     /// </summary>
-        /// <typeparam name="TOptions">The options type to validate.</typeparam>
+    /// <typeparam name="TOptions">The options type to validate.</typeparam>
     /// <typeparam name="TDep1">First dependency type.</typeparam>
     /// <typeparam name="TDep2">Second dependency type.</typeparam>
     /// <typeparam name="TDep3">Third dependency type.</typeparam>
@@ -301,7 +301,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency4">The fourth dependency.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, Func<TOptions, TDep1, TDep2, TDep3, TDep4, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -315,7 +315,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -353,12 +353,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options, Dependency1, Dependency2, Dependency3, Dependency4)).Value)
+                if (Validation.Invoke(options, Dependency1, Dependency2, Dependency3, Dependency4))
                 {
                     return ValidateOptionsResult.Success;
                 }
@@ -373,7 +373,7 @@ namespace Microsoft.Extensions.Options
     /// <summary>
     /// Implementation of <see cref="IValidateOptions{TOptions}"/>
     /// </summary>
-        /// <typeparam name="TOptions">The options type to validate.</typeparam>
+    /// <typeparam name="TOptions">The options type to validate.</typeparam>
     /// <typeparam name="TDep1">First dependency type.</typeparam>
     /// <typeparam name="TDep2">Second dependency type.</typeparam>
     /// <typeparam name="TDep3">Third dependency type.</typeparam>
@@ -392,7 +392,7 @@ namespace Microsoft.Extensions.Options
         /// <param name="dependency5">The fifth dependency.</param>
         /// <param name="validation">Validation function.</param>
         /// <param name="failureMessage">Validation failure message.</param>
-        public ValidateOptions(string name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation, string failureMessage)
+        public ValidateOptions(string? name, TDep1 dependency1, TDep2 dependency2, TDep3 dependency3, TDep4 dependency4, TDep5 dependency5, Func<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5, bool> validation!!, string failureMessage)
         {
             Name = name;
             Validation = validation;
@@ -407,7 +407,7 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// The options name.
         /// </summary>
-        public string Name { get; }
+        public string? Name { get; }
 
         /// <summary>
         /// The validation function.
@@ -450,12 +450,12 @@ namespace Microsoft.Extensions.Options
         /// <param name="name">The name of the options instance being validated.</param>
         /// <param name="options">The options instance.</param>
         /// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
-        public ValidateOptionsResult Validate(string name, TOptions options)
+        public ValidateOptionsResult Validate(string? name, TOptions options)
         {
             // null name is used to configure all named options
             if (Name == null || name == Name)
             {
-                if ((Validation?.Invoke(options, Dependency1, Dependency2, Dependency3, Dependency4, Dependency5)).Value)
+                if (Validation.Invoke(options, Dependency1, Dependency2, Dependency3, Dependency4, Dependency5))
                 {
                     return ValidateOptionsResult.Success;
                 }
index d4c769c..7630208 100644 (file)
@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 
 namespace Microsoft.Extensions.Options
 {
@@ -34,17 +35,19 @@ namespace Microsoft.Extensions.Options
         /// <summary>
         /// True if validation failed.
         /// </summary>
+        [MemberNotNullWhen(true, nameof(Failures))]
+        [MemberNotNullWhen(true, nameof(FailureMessage))]
         public bool Failed { get; protected set; }
 
         /// <summary>
         /// Used to describe why validation failed.
         /// </summary>
-        public string FailureMessage { get; protected set; }
+        public string? FailureMessage { get; protected set; }
 
         /// <summary>
         /// Full list of failures (can be multiple).
         /// </summary>
-        public IEnumerable<string> Failures { get; protected set; }
+        public IEnumerable<string>? Failures { get; protected set; }
 
         /// <summary>
         /// Returns a failure result.
index 7b94975..8866038 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System;
 using System.Collections.Generic;
 using Microsoft.Extensions.DependencyInjection;
 using Xunit;
@@ -74,5 +75,19 @@ namespace Microsoft.Extensions.Options.Tests
             }
         }
 
+        [Fact]
+        public void ValidationCannotBeNull()
+        {
+            string validName = "Name";
+            string validFailureMessage = "Something's wrong";
+            object validDependency = new();
+
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object>(validName, null, validFailureMessage));
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object, object>(validName, validDependency, null, validFailureMessage));
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object, object, object>(validName, validDependency, validDependency, null, validFailureMessage));
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object, object, object, object>(validName, validDependency, validDependency, validDependency, null, validFailureMessage));
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object, object, object, object, object>(validName, validDependency, validDependency, validDependency, validDependency, null, validFailureMessage));
+            Assert.Throws<ArgumentNullException>(() => new ValidateOptions<object, object, object, object, object, object>(validName, validDependency, validDependency, validDependency, validDependency, validDependency, null, validFailureMessage));
+        }
     }
 }