/
ElementReference.cs
74 lines (66 loc) · 2.93 KB
/
ElementReference.cs
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
// 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.Globalization;
using System.Threading;
namespace Microsoft.AspNetCore.Components
{
/// <summary>
/// Represents a reference to a rendered element.
/// </summary>
public readonly struct ElementReference
{
private static long _nextIdForWebAssemblyOnly = 1;
/// <summary>
/// Gets a unique identifier for <see cref="ElementReference" />.
/// </summary>
/// <remarks>
/// The Id is unique at least within the scope of a given user/circuit.
/// This property is public to support Json serialization and should not be used by user code.
/// </remarks>
public string Id { get; }
/// <summary>
/// Gets the <see cref="ElementReferenceContext"/> instance.
/// </summary>
public ElementReferenceContext? Context { get; }
/// <summary>
/// Instantiates a new <see cref="ElementReference" />.
/// </summary>
/// <param name="id">A unique identifier for this <see cref="ElementReference"/>.</param>
/// <param name="context">The nullable <see cref="ElementReferenceContext"/> instance.</param>
public ElementReference(string id, ElementReferenceContext? context)
{
Id = id;
Context = context;
}
/// <summary>
/// Instantiates a new <see cref="ElementReference"/>.
/// </summary>
/// <param name="id">A unique identifier for this <see cref="ElementReference"/>.</param>
public ElementReference(string id) : this(id, null)
{
}
internal static ElementReference CreateWithUniqueId(ElementReferenceContext? context)
=> new ElementReference(CreateUniqueId(), context);
private static string CreateUniqueId()
{
if (OperatingSystem.IsBrowser())
{
// On WebAssembly there's only one user, so it's fine to expose the number
// of IDs that have been assigned, and this is cheaper than creating a GUID.
// It's unfortunate that this still involves a heap allocation. If that becomes
// a problem we could extend RenderTreeFrame to have both "string" and "long"
// fields for ElementRefCaptureId, of which only one would be in use depending
// on the platform.
var id = Interlocked.Increment(ref _nextIdForWebAssemblyOnly);
return id.ToString(CultureInfo.InvariantCulture);
}
else
{
// For remote rendering, it's important not to disclose any cross-user state,
// such as the number of IDs that have been assigned.
return Guid.NewGuid().ToString("D", CultureInfo.InvariantCulture);
}
}
}
}