Skip to content
This repository was archived by the owner on Nov 7, 2018. It is now read-only.

Commit 53e879f

Browse files
author
Nate McMaster
committed
Merge branch 'release/2.2'
2 parents 133204d + dfcde1b commit 53e879f

20 files changed

+550
-18
lines changed

Options.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
3737
version.xml = version.xml
3838
EndProjectSection
3939
EndProject
40+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Options.DataAnnotations", "src\Microsoft.Extensions.Options.DataAnnotations\Microsoft.Extensions.Options.DataAnnotations.csproj", "{D0EB1487-D9E9-4C58-A907-BCD595993251}"
41+
EndProject
4042
Global
4143
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4244
Debug|Any CPU = Debug|Any CPU
@@ -55,6 +57,10 @@ Global
5557
{BA4EF3CE-1829-4E0E-8281-BD503FF8A682}.Debug|Any CPU.Build.0 = Debug|Any CPU
5658
{BA4EF3CE-1829-4E0E-8281-BD503FF8A682}.Release|Any CPU.ActiveCfg = Release|Any CPU
5759
{BA4EF3CE-1829-4E0E-8281-BD503FF8A682}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{D0EB1487-D9E9-4C58-A907-BCD595993251}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{D0EB1487-D9E9-4C58-A907-BCD595993251}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{D0EB1487-D9E9-4C58-A907-BCD595993251}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{D0EB1487-D9E9-4C58-A907-BCD595993251}.Release|Any CPU.Build.0 = Release|Any CPU
5864
EndGlobalSection
5965
GlobalSection(SolutionProperties) = preSolution
6066
HideSolutionNode = FALSE
@@ -63,6 +69,7 @@ Global
6369
{16BADE2F-1184-4518-8A70-B68A19D0805B} = {0A4664A0-CB48-4338-A6B7-02E28DF62CBA}
6470
{6ACF4BAB-2F09-4DA6-B273-27E4282865EB} = {10221BD9-FD19-4809-B680-7628CB87926B}
6571
{BA4EF3CE-1829-4E0E-8281-BD503FF8A682} = {10221BD9-FD19-4809-B680-7628CB87926B}
72+
{D0EB1487-D9E9-4C58-A907-BCD595993251} = {10221BD9-FD19-4809-B680-7628CB87926B}
6673
EndGlobalSection
6774
GlobalSection(ExtensibilityGlobals) = postSolution
6875
SolutionGuid = {A4D0BBDB-82DD-4B7E-981F-E6B90F3850B6}

src/Microsoft.Extensions.Options.ConfigurationExtensions/ConfigurationChangeTokenSource.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public ConfigurationChangeTokenSource(string name, IConfiguration config)
3737
Name = name ?? Options.DefaultName;
3838
}
3939

40+
/// <summary>
41+
/// The name of the option instance being changed.
42+
/// </summary>
4043
public string Name { get; }
4144

4245
/// <summary>

src/Microsoft.Extensions.Options.ConfigurationExtensions/Microsoft.Extensions.Options.ConfigurationExtensions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<Description>Provides additional configuration specific functionality related to Options.</Description>
55
<TargetFramework>netstandard2.0</TargetFramework>
6-
<NoWarn>$(NoWarn);CS1591</NoWarn>
6+
<NoWarn>$(NoWarn)</NoWarn>
77
<GenerateDocumentationFile>true</GenerateDocumentationFile>
88
<PackageTags>aspnetcore;configuration;options</PackageTags>
99
</PropertyGroup>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.ComponentModel.DataAnnotations;
7+
using System.Linq;
8+
9+
namespace Microsoft.Extensions.Options
10+
{
11+
/// <summary>
12+
/// Implementation of <see cref="IValidateOptions{TOptions}"/> that uses DataAnnotation's <see cref="Validator"/> for validation.
13+
/// </summary>
14+
/// <typeparam name="TOptions">The instance being validated.</typeparam>
15+
public class DataAnnotationValidateOptions<TOptions> : IValidateOptions<TOptions> where TOptions : class
16+
{
17+
/// <summary>
18+
/// Constructor.
19+
/// </summary>
20+
/// <param name="name"></param>
21+
public DataAnnotationValidateOptions(string name)
22+
{
23+
Name = name;
24+
}
25+
26+
/// <summary>
27+
/// The options name.
28+
/// </summary>
29+
public string Name { get; }
30+
31+
/// <summary>
32+
/// Validates a specific named options instance (or all when name is null).
33+
/// </summary>
34+
/// <param name="name">The name of the options instance being validated.</param>
35+
/// <param name="options">The options instance.</param>
36+
/// <returns>The <see cref="ValidateOptionsResult"/> result.</returns>
37+
public ValidateOptionsResult Validate(string name, TOptions options)
38+
{
39+
// Null name is used to configure all named options.
40+
if (Name == null || name == Name)
41+
{
42+
var validationResults = new List<ValidationResult>();
43+
if (Validator.TryValidateObject(options,
44+
new ValidationContext(options, serviceProvider: null, items: null),
45+
validationResults,
46+
validateAllProperties: true))
47+
{
48+
return ValidateOptionsResult.Success;
49+
}
50+
51+
return ValidateOptionsResult.Fail(String.Join(Environment.NewLine,
52+
validationResults.Select(r => "DataAnnotation validation failed for members " +
53+
String.Join(", ", r.MemberNames) +
54+
" with the error '" + r.ErrorMessage + "'.")));
55+
}
56+
57+
// Ignored if not validating this instance.
58+
return ValidateOptionsResult.Skip;
59+
}
60+
}
61+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Description>Provides additional DataAnnotations specific functionality related to Options.</Description>
5+
<TargetFramework>netstandard2.0</TargetFramework>
6+
<NoWarn>$(NoWarn)</NoWarn>
7+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
8+
<PackageTags>aspnetcore;validation;options</PackageTags>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\Microsoft.Extensions.Options\Microsoft.Extensions.Options.csproj" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
17+
<PackageReference Include="System.ComponentModel.Annotations" Version="$(SystemComponentModelAnnotationsPackageVersion)" />
18+
</ItemGroup>
19+
20+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.Extensions.Options;
5+
6+
namespace Microsoft.Extensions.DependencyInjection
7+
{
8+
/// <summary>
9+
/// Extension methods for adding configuration related options services to the DI container via <see cref="OptionsBuilder{TOptions}"/>.
10+
/// </summary>
11+
public static class OptionsBuilderDataAnnotationsExtensions
12+
{
13+
/// <summary>
14+
/// Register this options instance for validation of its DataAnnotations.
15+
/// </summary>
16+
/// <typeparam name="TOptions">The options type to be configured.</typeparam>
17+
/// <param name="optionsBuilder">The options builder to add the services to.</param>
18+
/// <returns>The <see cref="OptionsBuilder{TOptions}"/> so that additional calls can be chained.</returns>
19+
public static OptionsBuilder<TOptions> ValidateDataAnnotations<TOptions>(this OptionsBuilder<TOptions> optionsBuilder) where TOptions : class
20+
{
21+
optionsBuilder.Services.AddSingleton<IValidateOptions<TOptions>>(new DataAnnotationValidateOptions<TOptions>(optionsBuilder.Name));
22+
return optionsBuilder;
23+
}
24+
}
25+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

src/Microsoft.Extensions.Options/ConfigureNamedOptions.cs

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ public ConfigureNamedOptions(string name, Action<TOptions> action)
3535
/// <summary>
3636
/// Invokes the registered configure Action if the name matches.
3737
/// </summary>
38-
/// <param name="name"></param>
39-
/// <param name="options"></param>
38+
/// <param name="name">The name of the options instance being configured.</param>
39+
/// <param name="options">The options instance to configure.</param>
4040
public virtual void Configure(string name, TOptions options)
4141
{
4242
if (options == null)
@@ -51,6 +51,10 @@ public virtual void Configure(string name, TOptions options)
5151
}
5252
}
5353

54+
/// <summary>
55+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
56+
/// </summary>
57+
/// <param name="options">The options instance to configure.</param>
5458
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
5559
}
5660

@@ -86,8 +90,16 @@ public ConfigureNamedOptions(string name, TDep dependency, Action<TOptions, TDep
8690
/// </summary>
8791
public Action<TOptions, TDep> Action { get; }
8892

93+
/// <summary>
94+
/// The dependency.
95+
/// </summary>
8996
public TDep Dependency { get; }
9097

98+
/// <summary>
99+
/// Invokes the registered configure Action if the name matches.
100+
/// </summary>
101+
/// <param name="name">The name of the options instance being configured.</param>
102+
/// <param name="options">The options instance to configure.</param>
91103
public virtual void Configure(string name, TOptions options)
92104
{
93105
if (options == null)
@@ -102,6 +114,10 @@ public virtual void Configure(string name, TOptions options)
102114
}
103115
}
104116

117+
/// <summary>
118+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
119+
/// </summary>
120+
/// <param name="options">The options instance to configure.</param>
105121
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
106122
}
107123

@@ -141,10 +157,21 @@ public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, A
141157
/// </summary>
142158
public Action<TOptions, TDep1, TDep2> Action { get; }
143159

160+
/// <summary>
161+
/// The first dependency.
162+
/// </summary>
144163
public TDep1 Dependency1 { get; }
145164

165+
/// <summary>
166+
/// The second dependency.
167+
/// </summary>
146168
public TDep2 Dependency2 { get; }
147169

170+
/// <summary>
171+
/// Invokes the registered configure Action if the name matches.
172+
/// </summary>
173+
/// <param name="name">The name of the options instance being configured.</param>
174+
/// <param name="options">The options instance to configure.</param>
148175
public virtual void Configure(string name, TOptions options)
149176
{
150177
if (options == null)
@@ -159,6 +186,10 @@ public virtual void Configure(string name, TOptions options)
159186
}
160187
}
161188

189+
/// <summary>
190+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
191+
/// </summary>
192+
/// <param name="options">The options instance to configure.</param>
162193
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
163194
}
164195

@@ -202,13 +233,26 @@ public ConfigureNamedOptions(string name, TDep1 dependency, TDep2 dependency2, T
202233
/// </summary>
203234
public Action<TOptions, TDep1, TDep2, TDep3> Action { get; }
204235

236+
/// <summary>
237+
/// The first dependency.
238+
/// </summary>
205239
public TDep1 Dependency1 { get; }
206240

241+
/// <summary>
242+
/// The second dependency.
243+
/// </summary>
207244
public TDep2 Dependency2 { get; }
208245

246+
/// <summary>
247+
/// The third dependency.
248+
/// </summary>
209249
public TDep3 Dependency3 { get; }
210250

211-
251+
/// <summary>
252+
/// Invokes the registered configure Action if the name matches.
253+
/// </summary>
254+
/// <param name="name">The name of the options instance being configured.</param>
255+
/// <param name="options">The options instance to configure.</param>
212256
public virtual void Configure(string name, TOptions options)
213257
{
214258
if (options == null)
@@ -223,6 +267,10 @@ public virtual void Configure(string name, TOptions options)
223267
}
224268
}
225269

270+
/// <summary>
271+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
272+
/// </summary>
273+
/// <param name="options">The options instance to configure.</param>
226274
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
227275
}
228276

@@ -270,15 +318,31 @@ public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2,
270318
/// </summary>
271319
public Action<TOptions, TDep1, TDep2, TDep3, TDep4> Action { get; }
272320

321+
/// <summary>
322+
/// The first dependency.
323+
/// </summary>
273324
public TDep1 Dependency1 { get; }
274325

326+
/// <summary>
327+
/// The second dependency.
328+
/// </summary>
275329
public TDep2 Dependency2 { get; }
276330

331+
/// <summary>
332+
/// The third dependency.
333+
/// </summary>
277334
public TDep3 Dependency3 { get; }
278335

336+
/// <summary>
337+
/// The fourth dependency.
338+
/// </summary>
279339
public TDep4 Dependency4 { get; }
280340

281-
341+
/// <summary>
342+
/// Invokes the registered configure Action if the name matches.
343+
/// </summary>
344+
/// <param name="name">The name of the options instance being configured.</param>
345+
/// <param name="options">The options instance to configure.</param>
282346
public virtual void Configure(string name, TOptions options)
283347
{
284348
if (options == null)
@@ -293,6 +357,10 @@ public virtual void Configure(string name, TOptions options)
293357
}
294358
}
295359

360+
/// <summary>
361+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
362+
/// </summary>
363+
/// <param name="options">The options instance to configure.</param>
296364
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
297365
}
298366

@@ -344,17 +412,36 @@ public ConfigureNamedOptions(string name, TDep1 dependency1, TDep2 dependency2,
344412
/// </summary>
345413
public Action<TOptions, TDep1, TDep2, TDep3, TDep4, TDep5> Action { get; }
346414

415+
/// <summary>
416+
/// The first dependency.
417+
/// </summary>
347418
public TDep1 Dependency1 { get; }
348419

420+
/// <summary>
421+
/// The second dependency.
422+
/// </summary>
349423
public TDep2 Dependency2 { get; }
350424

425+
/// <summary>
426+
/// The third dependency.
427+
/// </summary>
351428
public TDep3 Dependency3 { get; }
352429

430+
/// <summary>
431+
/// The fourth dependency.
432+
/// </summary>
353433
public TDep4 Dependency4 { get; }
354434

435+
/// <summary>
436+
/// The fifth dependency.
437+
/// </summary>
355438
public TDep5 Dependency5 { get; }
356439

357-
440+
/// <summary>
441+
/// Invokes the registered configure Action if the name matches.
442+
/// </summary>
443+
/// <param name="name">The name of the options instance being configured.</param>
444+
/// <param name="options">The options instance to configure.</param>
358445
public virtual void Configure(string name, TOptions options)
359446
{
360447
if (options == null)
@@ -369,7 +456,10 @@ public virtual void Configure(string name, TOptions options)
369456
}
370457
}
371458

459+
/// <summary>
460+
/// Invoked to configure a TOptions instance with the <see cref="Options.DefaultName"/>.
461+
/// </summary>
462+
/// <param name="options">The options instance to configure.</param>
372463
public void Configure(TOptions options) => Configure(Options.DefaultName, options);
373464
}
374-
375465
}

src/Microsoft.Extensions.Options/IOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.Extensions.Options
1010
public interface IOptions<out TOptions> where TOptions : class, new()
1111
{
1212
/// <summary>
13-
/// The default configured TOptions instance, equivalent to Get(string.Empty).
13+
/// The default configured TOptions instance
1414
/// </summary>
1515
TOptions Value { get; }
1616
}

0 commit comments

Comments
 (0)