Skip to content

Commit 6c14f86

Browse files
committed
Add generated resolver
1 parent 309d27a commit 6c14f86

File tree

3 files changed

+288
-1
lines changed

3 files changed

+288
-1
lines changed

src/Microsoft.Diagnostics.Monitoring.WebApi/MonitorJsonSerializerContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace Microsoft.Diagnostics.Monitoring.WebApi
2525
[JsonSerializable(typeof(IEnumerable<ProcessIdentifier>))]
2626
[JsonSerializable(typeof(IList<ProcessIdentifier>))]
2727
[JsonSerializable(typeof(LogsConfiguration))]
28+
[JsonSerializable(typeof(MetricsOptions))]
2829
[JsonSerializable(typeof(OperationStatus))]
2930
[JsonSerializable(typeof(ProcessInfo))]
3031
[JsonSerializable(typeof(ProblemDetails))]

src/Tools/dotnet-monitor/Startup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.IO.Compression;
1616
using System.Text.Json.Serialization;
1717
using System.Reflection;
18+
using Microsoft.AspNetCore.Http.Validation.Generated;
1819

1920
namespace Microsoft.Diagnostics.Tools.Monitor
2021
{
@@ -35,7 +36,7 @@ public void ConfigureServices(IServiceCollection services)
3536
options.SerializerOptions.TypeInfoResolverChain.Add(MonitorJsonSerializerContext.Default);
3637
});
3738

38-
services.AddValidation();
39+
MyExtensions.AddValidation(services);
3940

4041
services.Configure<ApiBehaviorOptions>(options =>
4142
{
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
#nullable enable annotations
2+
//------------------------------------------------------------------------------
3+
// <auto-generated>
4+
// This code was generated by a tool.
5+
//
6+
// Changes to this file may cause incorrect behavior and will be lost if
7+
// the code is regenerated.
8+
// </auto-generated>
9+
//------------------------------------------------------------------------------
10+
#nullable enable
11+
12+
namespace System.Runtime.CompilerServices
13+
{
14+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
15+
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
16+
file sealed class InterceptsLocationAttribute : System.Attribute
17+
{
18+
public InterceptsLocationAttribute(int version, string data)
19+
{
20+
}
21+
}
22+
}
23+
24+
namespace Microsoft.AspNetCore.Http.Validation.Generated
25+
{
26+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
27+
file sealed class GeneratedValidatablePropertyInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatablePropertyInfo
28+
{
29+
public GeneratedValidatablePropertyInfo(
30+
[param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)]
31+
global::System.Type containingType,
32+
global::System.Type propertyType,
33+
string name,
34+
string displayName) : base(containingType, propertyType, name, displayName)
35+
{
36+
ContainingType = containingType;
37+
Name = name;
38+
}
39+
40+
[global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)]
41+
internal global::System.Type ContainingType { get; }
42+
internal string Name { get; }
43+
44+
protected override global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes()
45+
=> ValidationAttributeCache.GetValidationAttributes(ContainingType, Name);
46+
}
47+
48+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
49+
file sealed class GeneratedValidatableTypeInfo : global::Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo
50+
{
51+
public GeneratedValidatableTypeInfo(
52+
[param: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.Interfaces)]
53+
global::System.Type type,
54+
ValidatablePropertyInfo[] members) : base(type, members) { }
55+
}
56+
57+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
58+
file class GeneratedValidatableInfoResolver : global::Microsoft.AspNetCore.Http.Validation.IValidatableInfoResolver
59+
{
60+
public bool TryGetValidatableTypeInfo(global::System.Type type, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo)
61+
{
62+
System.Console.WriteLine("My TryGetValidatableTypeInfo");
63+
validatableInfo = null;
64+
if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider))
65+
{
66+
validatableInfo = CreateMetricProvider();
67+
return true;
68+
}
69+
if (type == typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions))
70+
{
71+
validatableInfo = CreateMetricsOptions();
72+
return true;
73+
}
74+
if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions))
75+
{
76+
validatableInfo = CreateMonitorApiKeyOptions();
77+
return true;
78+
}
79+
if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions))
80+
{
81+
validatableInfo = CreateAzureAdOptions();
82+
return true;
83+
}
84+
if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions))
85+
{
86+
validatableInfo = CreateAuthenticationOptions();
87+
return true;
88+
}
89+
if (type == typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes))
90+
{
91+
validatableInfo = CreateValidatableTypes();
92+
return true;
93+
}
94+
95+
return false;
96+
}
97+
98+
// No-ops, rely on runtime code for ParameterInfo-based resolution
99+
public bool TryGetValidatableParameterInfo(global::System.Reflection.ParameterInfo parameterInfo, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.AspNetCore.Http.Validation.IValidatableInfo? validatableInfo)
100+
{
101+
validatableInfo = null;
102+
return false;
103+
}
104+
105+
private ValidatableTypeInfo CreateMetricProvider()
106+
{
107+
return new GeneratedValidatableTypeInfo(
108+
type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider),
109+
members: [
110+
new GeneratedValidatablePropertyInfo(
111+
containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider),
112+
propertyType: typeof(string),
113+
name: "ProviderName",
114+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
115+
),
116+
]
117+
);
118+
}
119+
private ValidatableTypeInfo CreateMetricsOptions()
120+
{
121+
return new GeneratedValidatableTypeInfo(
122+
type: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions),
123+
members: [
124+
new GeneratedValidatablePropertyInfo(
125+
containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions),
126+
propertyType: typeof(int?),
127+
name: "MetricCount",
128+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
129+
),
130+
new GeneratedValidatablePropertyInfo(
131+
containingType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions),
132+
propertyType: typeof(global::System.Collections.Generic.List<global::Microsoft.Diagnostics.Monitoring.WebApi.MetricProvider>),
133+
name: "Providers",
134+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
135+
),
136+
]
137+
);
138+
}
139+
private ValidatableTypeInfo CreateMonitorApiKeyOptions()
140+
{
141+
return new GeneratedValidatableTypeInfo(
142+
type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions),
143+
members: [
144+
new GeneratedValidatablePropertyInfo(
145+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions),
146+
propertyType: typeof(string),
147+
name: "Subject",
148+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
149+
),
150+
new GeneratedValidatablePropertyInfo(
151+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions),
152+
propertyType: typeof(string),
153+
name: "PublicKey",
154+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
155+
),
156+
]
157+
);
158+
}
159+
private ValidatableTypeInfo CreateAzureAdOptions()
160+
{
161+
return new GeneratedValidatableTypeInfo(
162+
type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
163+
members: [
164+
new GeneratedValidatablePropertyInfo(
165+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
166+
propertyType: typeof(string),
167+
name: "TenantId",
168+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
169+
),
170+
new GeneratedValidatablePropertyInfo(
171+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
172+
propertyType: typeof(string),
173+
name: "ClientId",
174+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
175+
),
176+
new GeneratedValidatablePropertyInfo(
177+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
178+
propertyType: typeof(global::System.Uri),
179+
name: "AppIdUri",
180+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
181+
),
182+
new GeneratedValidatablePropertyInfo(
183+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
184+
propertyType: typeof(string),
185+
name: "RequiredRole",
186+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
187+
),
188+
]
189+
);
190+
}
191+
private ValidatableTypeInfo CreateAuthenticationOptions()
192+
{
193+
return new GeneratedValidatableTypeInfo(
194+
type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions),
195+
members: [
196+
new GeneratedValidatablePropertyInfo(
197+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions),
198+
propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.MonitorApiKeyOptions),
199+
name: "MonitorApiKey",
200+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
201+
),
202+
new GeneratedValidatablePropertyInfo(
203+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions),
204+
propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AzureAdOptions),
205+
name: "AzureAd",
206+
displayName: "Microsoft.Diagnostics.Monitoring.WebApi.OptionsDisplayStrings"
207+
),
208+
]
209+
);
210+
}
211+
private ValidatableTypeInfo CreateValidatableTypes()
212+
{
213+
return new GeneratedValidatableTypeInfo(
214+
type: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes),
215+
members: [
216+
new GeneratedValidatablePropertyInfo(
217+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes),
218+
propertyType: typeof(global::Microsoft.Diagnostics.Monitoring.WebApi.MetricsOptions),
219+
name: "MetricsOptions",
220+
displayName: "MetricsOptions"
221+
),
222+
new GeneratedValidatablePropertyInfo(
223+
containingType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.ValidatableTypes),
224+
propertyType: typeof(global::Microsoft.Diagnostics.Tools.Monitor.AuthenticationOptions),
225+
name: "AuthenticationOptions",
226+
displayName: "AuthenticationOptions"
227+
),
228+
]
229+
);
230+
}
231+
232+
}
233+
234+
static class MyExtensions
235+
{
236+
public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action<ValidationOptions>? configureOptions = null)
237+
{
238+
return GeneratedServiceCollectionExtensions.AddValidation(services, configureOptions);
239+
}
240+
}
241+
242+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
243+
file static class GeneratedServiceCollectionExtensions
244+
{
245+
// [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "KANyLGuJNiNmJ3Sx9yUA6pQGAABTdGFydHVwLmNz")]
246+
public static global::Microsoft.Extensions.DependencyInjection.IServiceCollection AddValidation(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::System.Action<ValidationOptions>? configureOptions = null)
247+
{
248+
System.Console.WriteLine("My AddValidation");
249+
// Use non-extension method to avoid infinite recursion.
250+
return global::Microsoft.Extensions.DependencyInjection.ValidationServiceCollectionExtensions.AddValidation(services, options =>
251+
{
252+
options.Resolvers.Insert(0, new GeneratedValidatableInfoResolver());
253+
if (configureOptions is not null)
254+
{
255+
configureOptions(options);
256+
}
257+
});
258+
}
259+
}
260+
261+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.AspNetCore.Http.ValidationsGenerator, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", "10.0.0.0")]
262+
file static class ValidationAttributeCache
263+
{
264+
private sealed record CacheKey([property: global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] global::System.Type ContainingType, string PropertyName);
265+
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<CacheKey, global::System.ComponentModel.DataAnnotations.ValidationAttribute[]> _cache = new();
266+
267+
public static global::System.ComponentModel.DataAnnotations.ValidationAttribute[] GetValidationAttributes(
268+
[global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)]
269+
global::System.Type containingType,
270+
string propertyName)
271+
{
272+
var key = new CacheKey(containingType, propertyName);
273+
return _cache.GetOrAdd(key, static k =>
274+
{
275+
var property = k.ContainingType.GetProperty(k.PropertyName);
276+
if (property == null)
277+
{
278+
return [];
279+
}
280+
281+
return [.. global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes<global::System.ComponentModel.DataAnnotations.ValidationAttribute>(property, inherit: true)];
282+
});
283+
}
284+
}
285+
}

0 commit comments

Comments
 (0)