| File: ElementReference.cs | Web Access |
| Project: src\aspnetcore\src\Components\Components\src\Microsoft.AspNetCore.Components.csproj (Microsoft.AspNetCore.Components) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; 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); } } }