forked from aspnet/AspNetWebStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDescriptorUtil.cs
More file actions
97 lines (87 loc) · 3.65 KB
/
DescriptorUtil.cs
File metadata and controls
97 lines (87 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Threading;
namespace System.Web.Mvc
{
internal static class DescriptorUtil
{
private static void AppendPartToUniqueIdBuilder(StringBuilder builder, object part)
{
if (part == null)
{
builder.Append("[-1]");
}
else
{
string partString = Convert.ToString(part, CultureInfo.InvariantCulture);
builder.AppendFormat("[{0}]{1}", partString.Length, partString);
}
}
public static void AppendUniqueId(StringBuilder builder, object part)
{
// We can special-case certain part types
MemberInfo memberInfo = part as MemberInfo;
if (memberInfo != null)
{
AppendPartToUniqueIdBuilder(builder, memberInfo.Module.ModuleVersionId);
AppendPartToUniqueIdBuilder(builder, memberInfo.MetadataToken);
return;
}
IUniquelyIdentifiable uniquelyIdentifiable = part as IUniquelyIdentifiable;
if (uniquelyIdentifiable != null)
{
AppendPartToUniqueIdBuilder(builder, uniquelyIdentifiable.UniqueId);
return;
}
AppendPartToUniqueIdBuilder(builder, part);
}
public static string CreateUniqueId(object part0, object part1)
{
StringBuilder builder = new StringBuilder();
AppendUniqueId(builder, part0);
AppendUniqueId(builder, part1);
return builder.ToString();
}
public static string CreateUniqueId(object part0, object part1, object part2)
{
StringBuilder builder = new StringBuilder();
AppendUniqueId(builder, part0);
AppendUniqueId(builder, part1);
AppendUniqueId(builder, part2);
return builder.ToString();
}
public static TDescriptor[] LazilyFetchOrCreateDescriptors<TReflection, TDescriptor, TArgument>(
ref TDescriptor[] cacheLocation,
Func<TArgument, TReflection[]> initializer,
Func<TReflection, TArgument, TDescriptor> converter,
TArgument state)
{
// did we already calculate this once?
TDescriptor[] existingCache = Interlocked.CompareExchange(ref cacheLocation, null, null);
if (existingCache != null)
{
return existingCache;
}
// Note: since this code operates on arrays it is more efficient to call simple array operations
// instead of LINQ-y extension methods such as Select and Where. DO NOT attempt to simplify this
// without testing the performance impact.
TReflection[] memberInfos = initializer(state);
List<TDescriptor> descriptorsList = new List<TDescriptor>(memberInfos.Length);
for (int i = 0; i < memberInfos.Length; i++)
{
TDescriptor descriptor = converter(memberInfos[i], state);
if (descriptor != null)
{
descriptorsList.Add(descriptor);
}
}
TDescriptor[] descriptors = descriptorsList.ToArray();
TDescriptor[] updatedCache = Interlocked.CompareExchange(ref cacheLocation, descriptors, null);
return updatedCache ?? descriptors;
}
}
}