|
| 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.ComponentModel; |
| 6 | +using System.Threading; |
| 7 | + |
| 8 | +namespace Microsoft.AspNetCore.Components |
| 9 | +{ |
| 10 | + /// <summary> |
| 11 | + /// Represents a reference to a rendered element. |
| 12 | + /// </summary> |
| 13 | + public readonly struct ElementReference |
| 14 | + { |
| 15 | + private static long _nextIdForWebAssemblyOnly = 1; |
| 16 | + |
| 17 | + /// <summary> |
| 18 | + /// Gets a unique identifier for <see cref="ElementRef" />. |
| 19 | + /// </summary> |
| 20 | + /// <remarks> |
| 21 | + /// The Id is unique at least within the scope of a given user/circuit. |
| 22 | + /// This property is public to support Json serialization and should not be used by user code. |
| 23 | + /// </remarks> |
| 24 | + [EditorBrowsable(EditorBrowsableState.Never)] |
| 25 | + public string __internalId { get; } |
| 26 | + |
| 27 | + internal string Id => __internalId; |
| 28 | + |
| 29 | + private ElementReference(string id) |
| 30 | + { |
| 31 | + __internalId = id; |
| 32 | + } |
| 33 | + |
| 34 | + internal static ElementReference CreateWithUniqueId() |
| 35 | + => new ElementReference(CreateUniqueId()); |
| 36 | + |
| 37 | + private static string CreateUniqueId() |
| 38 | + { |
| 39 | + if (PlatformInfo.IsWebAssembly) |
| 40 | + { |
| 41 | + // On WebAssembly there's only one user, so it's fine to expose the number |
| 42 | + // of IDs that have been assigned, and this is cheaper than creating a GUID. |
| 43 | + // It's unfortunate that this still involves a heap allocation. If that becomes |
| 44 | + // a problem we could extend RenderTreeFrame to have both "string" and "long" |
| 45 | + // fields for ElementRefCaptureId, of which only one would be in use depending |
| 46 | + // on the platform. |
| 47 | + var id = Interlocked.Increment(ref _nextIdForWebAssemblyOnly); |
| 48 | + return id.ToString(); |
| 49 | + } |
| 50 | + else |
| 51 | + { |
| 52 | + // For remote rendering, it's important not to disclose any cross-user state, |
| 53 | + // such as the number of IDs that have been assigned. |
| 54 | + return Guid.NewGuid().ToString("D"); |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | +} |
0 commit comments