diff --git a/plugins/dotnet/skills/dotnet-aot-compat/SKILL.md b/plugins/dotnet/skills/dotnet-aot-compat/SKILL.md
new file mode 100644
index 0000000000..16a6675c12
--- /dev/null
+++ b/plugins/dotnet/skills/dotnet-aot-compat/SKILL.md
@@ -0,0 +1,268 @@
+---
+name: dotnet-aot-compat
+description: >
+ Make .NET projects compatible with Native AOT and trimming by systematically
+ resolving IL trim/AOT analyzer warnings. USE FOR: making projects AOT-compatible,
+ fixing trimming warnings, resolving IL warnings (IL2026, IL2070, IL2067, IL2072,
+ IL3050), adding DynamicallyAccessedMembers annotations, enabling IsAotCompatible.
+ DO NOT USE FOR: publishing native AOT binaries, optimizing binary size, replacing
+ reflection-heavy libraries with alternatives.
+ INVOKES: no tools — pure knowledge skill.
+---
+
+# dotnet-aot-compat
+
+Make .NET projects compatible with Native AOT and trimming by systematically resolving all IL trim/AOT analyzer warnings.
+
+## When to Use This Skill
+
+- **"Make this project AOT-compatible"**
+- **"Fix trimming warnings"** or **"fix IL warnings"**
+- **"Resolve IL2070 / IL2067 / IL2072 / IL2026 / IL3050 warnings"**
+- **"Add DynamicallyAccessedMembers annotations"**
+- **"Enable IsAotCompatible in my .csproj"**
+- **"My project has trim analyzer warnings after upgrading to net8.0"**
+- **"Annotate reflection code for the trimmer"**
+
+## When Not to Use This Skill
+
+Do not use this skill when the project exclusively targets .NET Framework (net4x), which does not support the trim/AOT analyzers.
+
+## Prerequisites
+
+An existing .NET project targeting net8.0 or later (or multi-targeting with at least one net8.0+ TFM) and the corresponding .NET SDK installed.
+
+## Background: What AOT Compatibility Means
+
+Native AOT and the IL trimmer perform static analysis to determine what code is reachable. Reflection can break this analysis because the trimmer can't see what types/members are accessed at runtime. The `IsAotCompatible` property enables analyzers that flag these issues as build warnings (ILXXXX codes).
+
+## Critical Rules
+
+### ❌ Never suppress warnings incorrectly
+
+- **NEVER** use `#pragma warning disable` for IL warnings. It hides warnings from the Roslyn analyzer at build time, but the IL linker and AOT compiler still see the issue. The code will fail at trim/publish time.
+- **NEVER** use `[UnconditionalSuppressMessage]`. It tells both the analyzer AND the linker to ignore the warning, meaning the trimmer cannot verify safety. Raising an error at build time is always preferable to hiding the issue and having it silently break at runtime.
+
+### 💡 Preferred approaches
+
+- **Prefer** `[DynamicallyAccessedMembers]` annotations to flow type information through the call chain.
+- **Prefer** refactoring to eliminate patterns that break annotation flow (e.g., boxing `Type` through `object[]`).
+- **Use** `[RequiresUnreferencedCode]` / `[RequiresDynamicCode]` / `[RequiresAssemblyFiles]` to mark methods as fundamentally incompatible with trimming, propagating the requirement to callers. This surfaces the issue clearly rather than hiding it — callers must explicitly acknowledge the incompatibility.
+
+### Annotation flow is key
+
+The trimmer tracks `[DynamicallyAccessedMembers]` annotations through assignments, parameter passing, and return values. If this flow is broken (e.g., by boxing a `Type` into `object`, storing in an untyped collection, or casting through interfaces), the trimmer loses track and warns. The fix is to preserve the flow, not suppress the warning.
+
+## Step-by-Step Procedure
+
+> **Do not explore the codebase up-front.** The build warnings tell you exactly which files and lines need changes. Follow a tight loop: **build → pick a warning → open that file at that line → apply the fix recipe → rebuild**. Reading or analyzing source files beyond what a specific warning points you to is wasted effort and leads to timeouts. Let the compiler guide you.
+>
+> ❌ Do NOT run `find`, `ls`, or `grep` to understand the project structure before building. Do NOT read README, docs, or architecture files. Your first action should be Step 1 (enable AOT analysis), then build.
+
+### Step 1: Enable AOT analysis in the .csproj
+
+Add `IsAotCompatible`. If the project doesn't exclusively target net8.0+, add a TFM condition (AOT analysis requires net8.0+):
+
+```xml
+
+ true
+
+```
+
+This automatically sets `EnableTrimAnalyzer=true` and `EnableAotAnalyzer=true` for compatible TFMs. For multi-targeting projects (e.g., `netstandard2.0;net8.0`), the condition ensures no `NETSDK1210` warnings on older TFMs.
+
+### Step 2: Build and collect warnings
+
+```bash
+dotnet build -f --no-incremental 2>&1 | grep 'IL[0-9]\{4\}'
+```
+
+Sort and deduplicate. Common warning codes:
+- **IL2070**: Reflection call on a `Type` parameter missing `[DynamicallyAccessedMembers]`
+- **IL2067**: Passing an unannotated `Type` to a method expecting `[DynamicallyAccessedMembers]`
+- **IL2072**: Return value or extracted value missing annotation (often from unboxing)
+- **IL2057**: `Type.GetType(string)` with a non-constant argument
+- **IL2026**: Calling a method marked `[RequiresUnreferencedCode]`
+- **IL2050**: P/invoke method with COM marshalling parameters
+- **IL2075**: Return value flows into reflection without annotation
+- **IL2091**: Generic argument missing `[DynamicallyAccessedMembers]` required by constraint
+- **IL3000**: `Assembly.Location` returns empty string in single-file/AOT apps
+- **IL3050**: Calling a method marked `[RequiresDynamicCode]`
+
+### Step 3: Triage warnings by code (do NOT read every file)
+
+Group the warnings from Step 2 by warning code and count them. **Do not open individual files yet.** Identify the top 1-2 patterns by count — these drive your fix strategy:
+
+| Pattern | Typical fix |
+|---------|-------------|
+| Many IL2026 + IL3050 from `JsonSerializer` | **Go to Strategy C immediately** — create a `JsonSerializerContext`, then batch-update all call sites |
+| IL2070/IL2087 on `Type` parameters | Add `[DynamicallyAccessedMembers]` to the innermost method, then cascade outward |
+| IL2067 passing unannotated `Type` | Annotate the parameter at the source |
+
+**In most real projects, IL2026/IL3050 from JsonSerializer dominate.** Start with Strategy C unless the warning breakdown clearly shows otherwise. After the batch JSON fix, handle remaining warnings with Strategies A–B. Only use Strategy D as a last resort.
+
+### Step 4: Fix warnings iteratively (innermost first)
+
+Work from the **innermost** reflection call outward. Each fix may cascade new warnings to callers.
+
+**Stay warning-driven.** For each warning, open only the file and line the compiler reported, identify the pattern, apply the matching fix recipe below, and move on. Do not scan the codebase for similar patterns or try to understand the full architecture — fix what the compiler tells you, rebuild, and let new warnings guide the next change. Fix a small batch of warnings (5-10), then rebuild immediately to check progress.
+
+**Use sub-agents when available.** If you can launch sub-agents (e.g., via a `task` tool), dispatch **multiple sub-agents in parallel** to edit different files simultaneously. Keep the main loop focused on building, parsing warnings, and dispatching — delegate actual file edits to sub-agents. For batch JSON updates, give each sub-agent 5-10 files to update in one prompt. **After 2 build-fix cycles, dispatch all remaining file edits to sub-agents in parallel — do not continue fixing files sequentially.** Example:
+
+> Update these files to use source-generated JSON: `src/Models/Resource.Serialization.cs`, `src/Models/Identity.Serialization.cs`, `src/Models/Plan.Serialization.cs`. In each file, replace `JsonSerializer.Serialize(writer, value)` with `JsonSerializer.Serialize(writer, value, MyProjectJsonContext.Default.TypeName)` and `JsonSerializer.Deserialize(ref reader)` with `JsonSerializer.Deserialize(ref reader, MyProjectJsonContext.Default.TypeName)`. Only edit the JsonSerializer call sites.
+
+#### Strategy A: Add `[DynamicallyAccessedMembers]` (preferred)
+
+When a method uses reflection on a `Type` parameter, annotate the parameter to tell the trimmer what members are needed:
+
+```csharp
+using System.Diagnostics.CodeAnalysis;
+
+// Before (warns IL2070):
+void Process(Type t) {
+ var method = t.GetMethod("Foo"); // trimmer can't verify
+}
+
+// After (clean):
+void Process([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type t) {
+ var method = t.GetMethod("Foo"); // trimmer preserves public methods
+}
+```
+
+When you annotate a parameter, **all callers** must now pass properly annotated types. This cascades outward — follow each caller and annotate or refactor as needed. **The caller's annotation must include at least the same member types as the callee's.** If the callee requires `PublicConstructors | NonPublicConstructors`, the caller must specify the same or a superset — using only `NonPublicConstructors` will produce IL2091.
+
+#### Strategy B: Refactor to preserve annotation flow
+
+When annotation flow is broken by boxing (storing `Type` in `object`, `object[]`, or untyped collections), **refactor** to pass the `Type` directly:
+
+```csharp
+// BROKEN: Type boxed into object[], annotation lost
+void Process(object[] args) {
+ Type t = (Type)args[0]; // IL2072: annotation lost through boxing
+ Evaluate(t, ...);
+}
+
+// FIXED: Pass Type as a separate, annotated parameter
+void Process(
+ object[] args,
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type calleeType,
+ ...) {
+ Evaluate(calleeType, ...); // annotation flows cleanly
+}
+```
+
+Common patterns that break flow and how to fix them:
+- **`object[]` parameter bags**: Extract the `Type` into a dedicated annotated parameter
+- **Dictionary/List storage**: Use a typed field with annotation instead
+- **Interface indirection**: Add annotation to the interface method's parameter
+- **Property with boxing getter**: Annotate the property's return type
+
+#### Strategy C: Source-generated JSON serialization (batch fix)
+
+When most warnings are IL2026/IL3050 from `JsonSerializer.Serialize`/`Deserialize`, this is a single mechanical fix applied in bulk:
+
+1. **Collect affected types** — grep for all `JsonSerializer.Serialize` and `JsonSerializer.Deserialize` call sites. Extract the type being serialized (the `` in `Deserialize`, or the runtime type of the object in `Serialize`).
+
+2. **Create one `JsonSerializerContext`** with `[JsonSerializable]` for every type found. **Skip types from external packages** (e.g., `ResponseError` from `Azure.Core`) — they won't source-generate for types you don't own. Handle external types separately via Gotcha #1 below.
+
+```csharp
+[JsonSerializerContext]
+[JsonSerializable(typeof(ManagedServiceIdentity))]
+[JsonSerializable(typeof(SystemData))]
+// ... one attribute per type YOU OWN
+// Do NOT add types from external packages (e.g., ResponseError)
+internal partial class MyProjectJsonContext : JsonSerializerContext { }
+```
+
+3. **Batch-update all call sites** — do not read each file individually. Apply the pattern mechanically:
+ - `JsonSerializer.Serialize(obj)` → `JsonSerializer.Serialize(obj, MyProjectJsonContext.Default.TypeName)`
+ - `JsonSerializer.Deserialize(json)` → `JsonSerializer.Deserialize(json, MyProjectJsonContext.Default.TypeName)`
+
+ Find and update all call sites in one pass:
+ ```bash
+ # Find all files with JsonSerializer calls
+ grep -rl 'JsonSerializer\.\(Serialize\|Deserialize\)' src/ --include='*.cs'
+ ```
+ Then use sequential `edit` calls to apply the same transformation to every matching file. **Do not use `sed` for C# code** — generics like `Deserialize()` have angle brackets and nested parentheses that sed will mangle.
+
+4. **Build once** to verify. Remaining warnings will be non-serialization issues — handle those with Strategies A–B or D.
+
+#### Strategy D: `[RequiresUnreferencedCode]` (last resort)
+
+When a method fundamentally requires arbitrary reflection that cannot be statically described:
+
+```csharp
+[RequiresUnreferencedCode("Loads plugins by name using Assembly.Load")]
+public void LoadPlugin(string assemblyName) {
+ var asm = Assembly.Load(assemblyName);
+ // ...
+}
+```
+
+This propagates to callers — they must also be annotated with `[RequiresUnreferencedCode]`. Use sparingly; it marks the entire call chain as trim-incompatible.
+
+### Step 5: Rebuild and repeat
+
+After each small batch of fixes (5-10 warnings), rebuild with `--no-incremental` and check for new warnings. **Do not attempt to fix all warnings before rebuilding** — frequent rebuilds catch mistakes early and reveal cascading warnings. Fixes cascade — annotating an inner method may surface warnings in its callers. Repeat until `0 Warning(s)`.
+
+### Step 6: Validate all TFMs
+
+Build all target frameworks to ensure:
+- **0 IL warnings** on net8.0+ TFMs
+- **No NETSDK1210 warnings** (the `IsAotCompatible` condition handles this)
+- **Clean builds** on older TFMs (netstandard2.0, net472, etc.)
+
+```bash
+dotnet build # builds all TFMs
+```
+
+## Stop Signals
+
+- **Do not analyze more than 2-3 representative files per warning pattern.** After identifying the fix for a pattern, apply it to all matching files without reading each one first.
+- **Start fixing after one build.** Do not do a second analysis pass — begin implementing fixes for the most common warning pattern immediately after Step 3 triage.
+- Stop after achieving **0 IL warnings** for net8.0+ TFMs. Don't optimize or refactor already-clean annotations.
+- If a warning requires **architectural refactoring** beyond annotation flow fixes (e.g., replacing an entire serialization layer), document it and stop — don't rewrite large subsystems.
+- Limit to **3 build-fix iterations** per warning. If annotation flow doesn't resolve it after 3 attempts, escalate to `[RequiresUnreferencedCode]`.
+- Don't chase warnings in **third-party dependencies** you can't modify. Note them and move on.
+- If the user asked a scoped question (e.g., "fix warnings in this file"), don't expand to the entire project.
+
+## Polyfills for Older TFMs
+
+For multi-targeting projects that include netstandard2.0 or net472, you need polyfills for `DynamicallyAccessedMembersAttribute` and related types. See [references/polyfills.md](references/polyfills.md).
+
+## Common Gotchas
+
+1. **External types without AOT-safe serialization**: When a type comes from a dependency you can't modify (e.g., `ResponseError` from `Azure.Core`) and it lacks a source-generated serializer, `Options.GetConverter()` is reflection-based and will produce IL warnings. First check if the type implements `IJsonModel` (common in Azure SDK) — if so, bypass `JsonSerializer` entirely:
+
+```csharp
+// Before (IL2026 — JsonSerializer uses reflection):
+JsonSerializer.Serialize(writer, errorValue);
+
+// After (AOT-safe — uses IJsonModel directly):
+((IJsonModel)errorValue).Write(writer, ModelReaderWriterOptions.Json);
+
+// For deserialization:
+var error = ((IJsonModel)new ResponseError()).Create(ref reader, ModelReaderWriterOptions.Json);
+```
+
+Do **not** add the external type to your `JsonSerializerContext` — it won't source-generate for types you don't own. If the type doesn't implement `IJsonModel`, write a custom `JsonConverter` with manual `Utf8JsonReader`/`Utf8JsonWriter` logic and register it via `[JsonSourceGenerationOptions]` on your context.
+
+2. **Serialization libraries**: Most reflection-based serializers (e.g., `Newtonsoft.Json`, `XmlSerializer`) are not AOT-compatible. Migrate to a source-generation-based serializer such as `System.Text.Json` with a `JsonSerializerContext`. If migration is not feasible, mark the serialization call site with `[RequiresUnreferencedCode]`.
+
+3. **Shared projects / projitems**: When source is shared between multiple projects via ``, annotations added to shared code affect ALL consuming projects. Verify that all consumers still build cleanly.
+
+## References
+
+[Limitations](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8#limitations-of-native-aot-deployment)
+[Conceptual: Understanding trimming](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-concepts)
+[How-to: trim compat](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings)
+
+## Checklist
+
+- [ ] Added `` with TFM condition to .csproj
+- [ ] Built with AOT analyzers enabled (net8.0+ TFM)
+- [ ] Fixed all IL warnings via annotations or refactoring
+- [ ] No `#pragma warning disable` or `[UnconditionalSuppressMessage]` used for any IL warning
+- [ ] Polyfills present for older TFMs if needed
+- [ ] All target frameworks build with 0 warnings
+- [ ] Verified shared/linked source doesn't break sibling projects
diff --git a/plugins/dotnet/skills/dotnet-aot-compat/references/polyfills.md b/plugins/dotnet/skills/dotnet-aot-compat/references/polyfills.md
new file mode 100644
index 0000000000..a577f2e2c6
--- /dev/null
+++ b/plugins/dotnet/skills/dotnet-aot-compat/references/polyfills.md
@@ -0,0 +1,43 @@
+# Polyfills for Older TFMs
+
+`DynamicallyAccessedMembersAttribute` shipped in .NET 5. For projects targeting netstandard2.0 or net472, you need a polyfill. The trimmer recognizes the attribute by name, so a local copy works:
+
+```csharp
+#if !NET
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.ReturnValue |
+ AttributeTargets.GenericParameter | AttributeTargets.Parameter |
+ AttributeTargets.Property, Inherited = false)]
+ internal sealed class DynamicallyAccessedMembersAttribute : Attribute
+ {
+ public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
+ => MemberTypes = memberTypes;
+ public DynamicallyAccessedMemberTypes MemberTypes { get; }
+ }
+
+ [Flags]
+ internal enum DynamicallyAccessedMemberTypes
+ {
+ None = 0,
+ PublicParameterlessConstructor = 0x0001,
+ PublicConstructors = 0x0002 | PublicParameterlessConstructor,
+ NonPublicConstructors = 0x0004,
+ PublicMethods = 0x0008,
+ NonPublicMethods = 0x0010,
+ PublicFields = 0x0020,
+ NonPublicFields = 0x0040,
+ PublicNestedTypes = 0x0080,
+ NonPublicNestedTypes = 0x0100,
+ PublicProperties = 0x0200,
+ NonPublicProperties = 0x0400,
+ PublicEvents = 0x0800,
+ NonPublicEvents = 0x1000,
+ Interfaces = 0x2000,
+ All = ~None // Discouraged — prefer specific flags
+ }
+}
+#endif
+```
+
+Similarly for `RequiresUnreferencedCodeAttribute` and `UnconditionalSuppressMessageAttribute` if needed on older TFMs.
diff --git a/tests/dotnet/dotnet-aot-compat/after/.gitignore b/tests/dotnet/dotnet-aot-compat/after/.gitignore
new file mode 100644
index 0000000000..cd42ee34e8
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/.gitignore
@@ -0,0 +1,2 @@
+bin/
+obj/
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmClient.cs b/tests/dotnet/dotnet-aot-compat/after/ArmClient.cs
new file mode 100644
index 0000000000..2993823501
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmClient.cs
@@ -0,0 +1,315 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.Core;
+using Azure.Core.Pipeline;
+using Azure.ResourceManager.ManagementGroups;
+using Azure.ResourceManager.Resources;
+using Azure.ResourceManager.Resources.Models;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// The entry point for all ARM clients.
+ ///
+ public partial class ArmClient
+ {
+ private TenantResource _tenant;
+ private SubscriptionResource _defaultSubscription;
+ private readonly ClientDiagnostics _subscriptionClientDiagnostics;
+ private bool? _canUseTagResource;
+
+ internal virtual Dictionary ApiVersionOverrides { get; } = new Dictionary();
+ internal ConcurrentDictionary> ResourceApiVersionCache { get; } = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase);
+ internal ConcurrentDictionary NamespaceVersionCache { get; } = new ConcurrentDictionary();
+
+ ///
+ /// Initializes a new instance of the class for mocking.
+ ///
+ protected ArmClient()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A credential used to authenticate to an Azure Service.
+ /// If is null.
+#pragma warning disable AZC0007 // DO provide a minimal constructor that takes only the parameters required to connect to the service.
+ public ArmClient(TokenCredential credential) : this(credential, default, default)
+#pragma warning restore AZC0007 // DO provide a minimal constructor that takes only the parameters required to connect to the service.
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A credential used to authenticate to an Azure Service.
+ /// The id of the default Azure subscription.
+ /// If is null.
+ public ArmClient(TokenCredential credential, string defaultSubscriptionId) : this(credential, defaultSubscriptionId, default)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A credential used to authenticate to an Azure Service.
+ /// The id of the default Azure subscription.
+ /// The client parameters to use in these operations.
+ /// If is null.
+ public ArmClient(TokenCredential credential, string defaultSubscriptionId, ArmClientOptions options)
+ {
+ Argument.AssertNotNull(credential, nameof(credential));
+
+ options ??= new ArmClientOptions();
+ ArmEnvironment environment = options.Environment.HasValue ? options.Environment.Value : ArmEnvironment.AzurePublicCloud;
+
+ Argument.AssertNotNull(environment.Endpoint, nameof(environment.Endpoint));
+
+ Endpoint = environment.Endpoint;
+
+ Pipeline = HttpPipelineBuilder.Build(options, new BearerTokenAuthenticationPolicy(credential, environment.DefaultScope));
+
+ Diagnostics = options.Diagnostics;
+ _subscriptionClientDiagnostics = new ClientDiagnostics("Azure.ResourceManager", SubscriptionResource.ResourceType.Namespace, Diagnostics);
+
+ CopyApiVersionOverrides(options);
+
+ _tenant = new TenantResource(this);
+ _defaultSubscription = string.IsNullOrWhiteSpace(defaultSubscriptionId) ? null :
+ new SubscriptionResource(this, SubscriptionResource.CreateResourceIdentifier(defaultSubscriptionId));
+ }
+
+ internal virtual bool CanUseTagResource(CancellationToken cancellationToken = default)
+ {
+ if (_canUseTagResource == null)
+ {
+ var tagRp = GetDefaultSubscription(cancellationToken).GetResourceProvider(TagResource.ResourceType.Namespace, cancellationToken: cancellationToken);
+ _canUseTagResource = tagRp.Value.Data.ResourceTypes.Any(rp => rp.ResourceType == TagResource.ResourceType.Type);
+ }
+ return _canUseTagResource.Value;
+ }
+
+ internal virtual async Task CanUseTagResourceAsync(CancellationToken cancellationToken = default)
+ {
+ if (_canUseTagResource == null)
+ {
+ var tagRp = await GetDefaultSubscription(cancellationToken).GetResourceProviderAsync(TagResource.ResourceType.Namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
+ _canUseTagResource = tagRp.Value.Data.ResourceTypes.Any(rp => rp.ResourceType == TagResource.ResourceType.Type);
+ }
+ return _canUseTagResource.Value;
+ }
+
+ private void CopyApiVersionOverrides(ArmClientOptions options)
+ {
+ foreach (var keyValuePair in options.ResourceApiVersionOverrides)
+ {
+ ApiVersionOverrides.Add(keyValuePair.Key, keyValuePair.Value);
+ }
+ }
+
+ ///
+ /// Gets the api version override if it has been set for the current client options.
+ ///
+ /// The resource type to get the version for.
+ /// The api version to variable to set.
+ internal virtual bool TryGetApiVersion(ResourceType resourceType, out string apiVersion)
+ {
+ return ApiVersionOverrides.TryGetValue(resourceType, out apiVersion);
+ }
+
+ ///
+ /// Gets the diagnostic options used for this client.
+ ///
+ internal virtual DiagnosticsOptions Diagnostics { get; }
+
+ ///
+ /// Gets the base URI of the service.
+ ///
+ internal virtual Uri Endpoint { get; private set; }
+
+ ///
+ /// Gets the HTTP pipeline.
+ ///
+ internal virtual HttpPipeline Pipeline { get; private set; }
+
+ ///
+ /// Gets the Azure subscriptions.
+ ///
+ /// Subscription collection.
+ public virtual SubscriptionCollection GetSubscriptions() => _tenant.GetSubscriptions();
+
+ ///
+ /// Gets the tenants.
+ ///
+ /// Tenant collection.
+ public virtual TenantCollection GetTenants()
+ {
+ return new TenantCollection(this);
+ }
+
+ ///
+ /// Gets the default subscription.
+ ///
+ /// Resource operations of the Subscription.
+#pragma warning disable AZC0015 // Unexpected client method return type.
+ public virtual SubscriptionResource GetDefaultSubscription(CancellationToken cancellationToken = default)
+#pragma warning restore AZC0015 // Unexpected client method return type.
+ {
+ using var scope = _subscriptionClientDiagnostics.CreateScope("ArmClient.GetDefaultSubscription");
+ scope.Start();
+ try
+ {
+ if (_defaultSubscription == null)
+ {
+ _defaultSubscription = GetSubscriptions().GetAll(cancellationToken).FirstOrDefault();
+ }
+ else if (_defaultSubscription.HasData)
+ {
+ return _defaultSubscription;
+ }
+ else
+ {
+ _defaultSubscription = _defaultSubscription.Get(cancellationToken);
+ }
+ if (_defaultSubscription is null)
+ {
+ throw new InvalidOperationException("No subscriptions found for the given credentials");
+ }
+ return _defaultSubscription;
+ }
+ catch (Exception e)
+ {
+ scope.Failed(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Gets the default subscription.
+ ///
+ /// Resource operations of the Subscription.
+#pragma warning disable AZC0015 // Unexpected client method return type.
+ public virtual async Task GetDefaultSubscriptionAsync(CancellationToken cancellationToken = default)
+#pragma warning restore AZC0015 // Unexpected client method return type.
+ {
+ using var scope = _subscriptionClientDiagnostics.CreateScope("ArmClient.GetDefaultSubscription");
+ scope.Start();
+ try
+ {
+ if (_defaultSubscription == null)
+ {
+ _defaultSubscription = await GetSubscriptions().GetAllAsync(cancellationToken).FirstOrDefaultAsync(_ => true, cancellationToken).ConfigureAwait(false);
+ }
+ else if (_defaultSubscription.HasData)
+ {
+ return _defaultSubscription;
+ }
+ else
+ {
+ _defaultSubscription = await _defaultSubscription.GetAsync(cancellationToken).ConfigureAwait(false);
+ }
+ if (_defaultSubscription is null)
+ {
+ throw new InvalidOperationException("No subscriptions found for the given credentials");
+ }
+ return _defaultSubscription;
+ }
+ catch (Exception e)
+ {
+ scope.Failed(e);
+ throw;
+ }
+ }
+
+ /// Gets a collection of GenericResources.
+ /// An object representing collection of GenericResources and their operations.
+ public virtual GenericResourceCollection GetGenericResources() => _tenant.GetGenericResources();
+
+ /// Gets all resource providers for a subscription.
+ /// [This parameter is no longer supported.] The number of results to return.
+ /// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider metadata. To include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ [ForwardsClientCalls]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.ObsoleteAttribute("This method is obsolete as the `top` parameter is not supported by service and will be removed in a future release.", false)]
+ public virtual Pageable GetTenantResourceProviders(int? top, string expand, CancellationToken cancellationToken = default) => _tenant.GetTenantResourceProviders(expand, cancellationToken);
+
+ /// Gets all resource providers for a subscription.
+ /// [This parameter is no longer supported.] The number of results to return.
+ /// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider metadata. To include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ [ForwardsClientCalls]
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+ [System.ObsoleteAttribute("This method is obsolete as the `top` parameter is not supported by service and will be removed in a future release.", false)]
+ public virtual AsyncPageable GetTenantResourceProvidersAsync(int? top, string expand, CancellationToken cancellationToken = default) => _tenant.GetTenantResourceProvidersAsync(expand, cancellationToken);
+
+ /// Gets all resource providers for a subscription.
+ /// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider metadata. To include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ [ForwardsClientCalls]
+ public virtual Pageable GetTenantResourceProviders(string expand = null, CancellationToken cancellationToken = default) => _tenant.GetTenantResourceProviders(expand, cancellationToken);
+
+ /// Gets all resource providers for a subscription.
+ /// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider metadata. To include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ [ForwardsClientCalls]
+ public virtual AsyncPageable GetTenantResourceProvidersAsync(string expand = null, CancellationToken cancellationToken = default) => _tenant.GetTenantResourceProvidersAsync(expand, cancellationToken);
+
+ /// Gets the specified resource provider at the tenant level.
+ /// The namespace of the resource provider.
+ /// The $expand query parameter. For example, to include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ /// is null.
+ [ForwardsClientCalls]
+ public virtual Response GetTenantResourceProvider(string resourceProviderNamespace, string expand = null, CancellationToken cancellationToken = default) => _tenant.GetTenantResourceProvider(resourceProviderNamespace, expand, cancellationToken);
+
+ /// Gets the specified resource provider at the tenant level.
+ /// The namespace of the resource provider.
+ /// The $expand query parameter. For example, to include property aliases in response, use $expand=resourceTypes/aliases.
+ /// The cancellation token to use.
+ /// is null.
+ [ForwardsClientCalls]
+ public virtual async Task> GetTenantResourceProviderAsync(string resourceProviderNamespace, string expand = null, CancellationToken cancellationToken = default) => await _tenant.GetTenantResourceProviderAsync(resourceProviderNamespace, expand, cancellationToken).ConfigureAwait(false);
+
+ ///
+ /// Gets the management group collection for this tenant.
+ ///
+ /// A collection of the management groups.
+ public virtual ManagementGroupCollection GetManagementGroups() => _tenant.GetManagementGroups();
+
+ ///
+ /// Gets a client using this instance of ArmClient to copy the client settings from.
+ ///
+ /// The type of that will be constructed.
+ /// Delegate method that will construct the client.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public virtual T GetResourceClient(Func resourceFactory)
+ where T : ArmResource
+ {
+ return resourceFactory();
+ }
+
+ private readonly ConcurrentDictionary _clientCache = new ConcurrentDictionary();
+
+ ///
+ /// Gets a cached client to use for extension methods.
+ ///
+ /// The type of client to get.
+ /// The constructor factory for the client.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public virtual T GetCachedClient(Func clientFactory)
+ where T : class
+ {
+ return _clientCache.GetOrAdd(typeof(T), (type) => { return clientFactory(this); }) as T;
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmClientOptions.cs b/tests/dotnet/dotnet-aot-compat/after/ArmClientOptions.cs
new file mode 100644
index 0000000000..6b60ffcab6
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmClientOptions.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text.Json;
+using Azure.Core;
+using Azure.ResourceManager.Resources;
+using Azure.ResourceManager;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// A class representing Azure resource manager client options.
+ ///
+#pragma warning disable AZC0008 // ClientOptions should have a nested enum called ServiceVersion
+ public sealed class ArmClientOptions : ClientOptions
+#pragma warning restore AZC0008 // ClientOptions should have a nested enum called ServiceVersion
+ {
+ internal IDictionary ResourceApiVersionOverrides { get; } = new Dictionary();
+
+ ///
+ /// Gets or sets Azure cloud environment.
+ ///
+ public ArmEnvironment? Environment { get; set; }
+
+ ///
+ /// Sets the api version to use for a given resource type.
+ /// To find which API Versions are available in your environment you can use the method
+ /// for the provider namespace you are interested in.
+ ///
+ /// The resource type to set the version for. To determine the appropriate value, you can refer to the corresponding documentation or XML documentation comments of the API. Then, get its resource type from the Resource's ResourceType field.
+ /// The api version to use.
+ public void SetApiVersion(ResourceType resourceType, string apiVersion)
+ {
+ Argument.AssertNotNullOrEmpty(apiVersion, nameof(apiVersion));
+
+ ResourceApiVersionOverrides[resourceType] = apiVersion;
+ }
+
+ ///
+ /// Sets the api versions from an Azure Stack profile.
+ ///
+ public void SetApiVersionsFromProfile(AzureStackProfile profile)
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+ using (Stream stream = assembly.GetManifestResourceStream(profile.GetManifestName()))
+ {
+ var span = BinaryData.FromStream(stream).ToMemory().Span;
+ var allProfile = JsonSerializer.Deserialize(span, ResourceManagerJsonContext.Default.DictionaryStringDictionaryStringJsonElement);
+ var armProfile = allProfile["resource-manager"];
+ foreach (var keyValuePair in armProfile)
+ {
+ var namespaceName = keyValuePair.Key;
+ var element = keyValuePair.Value;
+
+ foreach (var apiVersionProperty in element.EnumerateObject())
+ {
+ var apiVersion = apiVersionProperty.Name;
+ foreach (var resourceTypeItem in apiVersionProperty.Value.EnumerateArray())
+ {
+ string resourceTypeName = default;
+ foreach (var property in resourceTypeItem.EnumerateObject())
+ {
+ if (property.NameEquals("resourceType"))
+ {
+ resourceTypeName = property.Value.GetString();
+ break;
+ }
+ }
+ var resourceType = $"{namespaceName}/{resourceTypeName}";
+ ResourceApiVersionOverrides[resourceType] = apiVersion;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmCollection.cs b/tests/dotnet/dotnet-aot-compat/after/ArmCollection.cs
new file mode 100644
index 0000000000..c3b5b1b084
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmCollection.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Concurrent;
+using System.ComponentModel;
+using Azure.Core;
+using Azure.Core.Pipeline;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// Base class representing collection of resources.
+ ///
+ public abstract class ArmCollection
+ {
+ private readonly ConcurrentDictionary _clientCache = new ConcurrentDictionary();
+
+ ///
+ /// Initializes a new instance of the class for mocking.
+ ///
+ protected ArmCollection()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The client to copy settings from.
+ /// The id of the parent for the collection.
+ protected ArmCollection(ArmClient client, ResourceIdentifier id)
+ {
+ Argument.AssertNotNull(id, nameof(id));
+ Argument.AssertNotNull(client, nameof(client));
+
+ Client = client;
+ Id = id;
+ }
+
+ ///
+ /// Gets the resource identifier.
+ ///
+ public virtual ResourceIdentifier Id { get; }
+
+ ///
+ /// Gets the this resource client was created from.
+ ///
+ protected internal virtual ArmClient Client { get; }
+
+ ///
+ /// Gets the diagnostic options for this resource client.
+ ///
+ protected internal DiagnosticsOptions Diagnostics => Client.Diagnostics;
+
+ ///
+ /// Gets the pipeline for this resource client.
+ ///
+ protected internal HttpPipeline Pipeline => Client.Pipeline;
+
+ ///
+ /// Gets the base uri for this resource client.
+ ///
+ protected internal Uri Endpoint => Client.Endpoint;
+
+ ///
+ /// Gets the api version override if it has been set for the current client options.
+ ///
+ /// The resource type to get the version for.
+ /// The api version to variable to set.
+ protected bool TryGetApiVersion(ResourceType resourceType, out string apiVersion) => Client.TryGetApiVersion(resourceType, out apiVersion);
+
+ ///
+ /// Gets a cached client to use for extension methods.
+ ///
+ /// The type of client to get.
+ /// The constructor factory for the client.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public virtual T GetCachedClient(Func clientFactory)
+ where T : class
+ {
+ return _clientCache.GetOrAdd(typeof(T), (type) => { return clientFactory(Client); }) as T;
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmEnvironment.cs b/tests/dotnet/dotnet-aot-compat/after/ArmEnvironment.cs
new file mode 100644
index 0000000000..ccd1d5ede9
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmEnvironment.cs
@@ -0,0 +1,82 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Text.Json;
+using System.ComponentModel;
+using Azure.Core;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// ArmEnvrionment represents the information of an Azure Cloud environment.
+ ///
+ public readonly struct ArmEnvironment : IEquatable
+ {
+ // name after the `name` property of returned audience from https://management.azure.com/metadata/endpoints?api-version=2019-11-01
+ /// Azure Public Cloud.
+ public static readonly ArmEnvironment AzurePublicCloud = new(new Uri("https://management.azure.com"), "https://management.azure.com/");
+
+ /// Azure China Cloud.
+ public static readonly ArmEnvironment AzureChina = new(new Uri("https://management.chinacloudapi.cn"), "https://management.chinacloudapi.cn");
+
+ /// Azure US Government.
+ public static readonly ArmEnvironment AzureGovernment = new(new Uri("https://management.usgovcloudapi.net"), "https://management.usgovcloudapi.net");
+
+ /// Azure German Cloud.
+ public static readonly ArmEnvironment AzureGermany = new(new Uri("https://management.microsoftazure.de"), "https://management.microsoftazure.de");
+
+ ///
+ /// Gets base URI of the management API endpoint.
+ ///
+ public readonly Uri Endpoint { get; }
+
+ ///
+ /// Gets authentication audience.
+ ///
+ public readonly string Audience { get; }
+
+ ///
+ /// Gets default authentication scope.
+ ///
+ public string DefaultScope { get; }
+
+ ///
+ /// Construct an using the given value.
+ ///
+ /// Management API endpoint base URI.
+ /// Authentication audience.
+ public ArmEnvironment(Uri endpoint, string audience)
+ {
+ Argument.AssertNotNull(endpoint, nameof(endpoint));
+ Argument.AssertNotNullOrWhiteSpace(audience, nameof(audience));
+
+ Endpoint = endpoint;
+ Audience = audience;
+ DefaultScope = $"{Audience}/.default";
+ }
+
+ /// Determines if two values are the same.
+ public static bool operator ==(ArmEnvironment left, ArmEnvironment right) => left.Equals(right);
+
+ /// Determines if two values are not the same. internal
+ public static bool operator !=(ArmEnvironment left, ArmEnvironment right) => !left.Equals(right);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj) => obj is ArmEnvironment other && Equals(other);
+
+ ///
+ public bool Equals(ArmEnvironment other) => string.Equals(Audience, other.Audience, StringComparison.Ordinal) && Endpoint.Equals(other.Endpoint);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode()
+ {
+ return HashCodeBuilder.Combine(Endpoint, Audience);
+ }
+
+ ///
+ public override string ToString() => JsonSerializer.Serialize(this, ResourceManagerJsonContext.Default.ArmEnvironment);
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmOperation.cs b/tests/dotnet/dotnet-aot-compat/after/ArmOperation.cs
new file mode 100644
index 0000000000..e7e016f29f
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmOperation.cs
@@ -0,0 +1,116 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System.ClientModel.Primitives;
+using System.Reflection;
+using System;
+using Azure.Core;
+using Azure.Core.Pipeline;
+using System.Threading.Tasks;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Azure.ResourceManager
+{
+ ///
+ public abstract class ArmOperation : Operation
+ {
+ ///
+ /// Rehydrates an operation from a .
+ ///
+ /// The Arm client.
+ /// The rehydration token.
+ /// The Arm client options.
+ /// The long-running operation.
+ public static ArmOperation Rehydrate(ArmClient client, RehydrationToken rehydrationToken, ArmClientOptions options = null)
+ {
+ Argument.AssertNotNull(client, nameof(client));
+ Argument.AssertNotNull(rehydrationToken, nameof(rehydrationToken));
+
+ var nextLinkOperation = (NextLinkOperationImplementation)NextLinkOperationImplementation.Create(client.Pipeline, rehydrationToken);
+ var operationState = nextLinkOperation.UpdateStateAsync(async: false, default).EnsureCompleted();
+ return new RehydrationOperation(nextLinkOperation, operationState);
+ }
+
+ ///
+ /// Rehydrates an operation from a .
+ ///
+ /// The Arm client.
+ /// The rehydration token.
+ /// The Arm client options.
+ /// The long-running operation.
+ public static ArmOperation Rehydrate<[DynamicallyAccessedMembers(RehydrateMembers)] T>(ArmClient client, RehydrationToken rehydrationToken, ArmClientOptions options = null) where T : notnull
+ {
+
+ Argument.AssertNotNull(client, nameof(client));
+ Argument.AssertNotNull(rehydrationToken, nameof(rehydrationToken));
+
+ bool isResource = IsResource();
+ IOperationSource source = new GenericOperationSource(client, isResource);
+ var nextLinkOperation = (NextLinkOperationImplementation)NextLinkOperationImplementation.Create(client.Pipeline, rehydrationToken);
+ var operation = NextLinkOperationImplementation.Create(source, nextLinkOperation);
+ var operationState = operation.UpdateStateAsync(async: false, default).EnsureCompleted();
+ return new RehydrationOperation(nextLinkOperation, operationState, operation, options);
+ }
+
+ ///
+ /// Rehydrates an operation from a .
+ ///
+ /// The Arm client.
+ /// The rehydration token.
+ /// The Arm client options.
+ /// The long-running operation.
+ public static async Task RehydrateAsync(ArmClient client, RehydrationToken rehydrationToken, ArmClientOptions options = null)
+ {
+ Argument.AssertNotNull(client, nameof(client));
+ Argument.AssertNotNull(rehydrationToken, nameof(rehydrationToken));
+
+ var nextLinkOperation = (NextLinkOperationImplementation)NextLinkOperationImplementation.Create(client.Pipeline, rehydrationToken);
+ var operationState = await nextLinkOperation.UpdateStateAsync(async: true, default).ConfigureAwait(false);
+ return new RehydrationOperation(nextLinkOperation, operationState);
+ }
+
+ const DynamicallyAccessedMemberTypes RehydrateMembers = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
+
+ ///
+ /// Rehydrates an operation from a .
+ ///
+ /// The Arm client.
+ /// The rehydration token.
+ /// The Arm client options.
+ /// The long-running operation.
+ public static async Task> RehydrateAsync<[DynamicallyAccessedMembers(RehydrateMembers)] T>(ArmClient client, RehydrationToken rehydrationToken, ArmClientOptions options = null) where T : notnull
+ {
+
+ Argument.AssertNotNull(client, nameof(client));
+ Argument.AssertNotNull(rehydrationToken, nameof(rehydrationToken));
+
+ bool isResource = IsResource();
+ IOperationSource source = new GenericOperationSource(client, isResource);
+ var nextLinkOperation = (NextLinkOperationImplementation)NextLinkOperationImplementation.Create(client.Pipeline, rehydrationToken);
+ var operation = NextLinkOperationImplementation.Create(source, nextLinkOperation);
+ var operationState = await operation.UpdateStateAsync(async: true, default).ConfigureAwait(false);
+ return new RehydrationOperation(nextLinkOperation, operationState, operation, options);
+ }
+
+ private static bool IsResource<[DynamicallyAccessedMembers(RehydrateMembers)] T>() where T : notnull
+ {
+ var isResource = typeof(T).GetConstructor(
+ BindingFlags.NonPublic | BindingFlags.Instance,
+ null,
+ CallingConventions.Any,
+ new Type[] { typeof(ArmClient), typeof(ResourceIdentifier) },
+ null) is not null;
+ var obj = Activator.CreateInstance(typeof(T), BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);
+ if (!isResource && obj is not IJsonModel)
+ {
+ throw new InvalidOperationException($"Type {typeof(T)} should be Resource or Model");
+ }
+
+ return isResource;
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmOperationOfT.cs b/tests/dotnet/dotnet-aot-compat/after/ArmOperationOfT.cs
new file mode 100644
index 0000000000..5b23a5d6a7
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmOperationOfT.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+
+namespace Azure.ResourceManager
+{
+ ///
+ public abstract class ArmOperation : Operation
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/ArmResource.cs b/tests/dotnet/dotnet-aot-compat/after/ArmResource.cs
new file mode 100644
index 0000000000..3e5e82e19b
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/ArmResource.cs
@@ -0,0 +1,140 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Azure.Core;
+using Azure.Core.Pipeline;
+using Azure.ResourceManager.Resources;
+using Azure.ResourceManager.Resources.Models;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// A class representing the operations that can be performed over a specific resource.
+ ///
+ public abstract partial class ArmResource
+ {
+ private readonly ConcurrentDictionary _clientCache = new ConcurrentDictionary();
+
+ ///
+ /// Initializes a new instance of the class for mocking.
+ ///
+ protected ArmResource()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The this resource client should be created from.
+ /// The identifier of the resource that is the target of operations.
+ protected internal ArmResource(ArmClient client, ResourceIdentifier id)
+ {
+ Argument.AssertNotNull(id, nameof(id));
+ Argument.AssertNotNull(client, nameof(client));
+
+ Client = client;
+ Id = id;
+ }
+
+ ///
+ /// Gets the resource identifier.
+ ///
+ public virtual ResourceIdentifier Id { get; }
+
+ ///
+ /// Gets the this resource client was created from.
+ ///
+ protected internal virtual ArmClient Client { get; }
+
+ ///
+ /// Gets the diagnostic options for this resource client.
+ ///
+ protected internal DiagnosticsOptions Diagnostics => Client.Diagnostics;
+
+ ///
+ /// Gets the pipeline for this resource client.
+ ///
+ protected internal HttpPipeline Pipeline => Client.Pipeline;
+
+ ///
+ /// Gets the base uri for this resource client.
+ ///
+ protected internal Uri Endpoint => Client.Endpoint;
+
+ ///
+ /// Gets the api version override if it has been set for the current client options.
+ ///
+ /// The resource type to get the version for.
+ /// The api version to variable to set.
+ protected virtual bool TryGetApiVersion(ResourceType resourceType, out string apiVersion) => Client.TryGetApiVersion(resourceType, out apiVersion);
+
+ ///
+ /// Lists all available geo-locations.
+ ///
+ /// A token to allow the caller to cancel the call to the service. The default value is .
+ /// A collection of location that may take multiple service requests to iterate over.
+ [ForwardsClientCalls]
+ public virtual Response> GetAvailableLocations(CancellationToken cancellationToken = default)
+ {
+ string nameSpace = Id.ResourceType.Namespace;
+ string type = Id.ResourceType.Type;
+ Response resourcePageableProviderResponse = Client.GetTenantResourceProvider(nameSpace, null, cancellationToken);
+ TenantResourceProvider resourcePageableProvider = resourcePageableProviderResponse.Value;
+ if (resourcePageableProvider is null)
+ throw new InvalidOperationException($"{type} not found for {nameSpace}");
+ var theResource = resourcePageableProvider.ResourceTypes.FirstOrDefault(r => type.Equals(r.ResourceType, StringComparison.Ordinal));
+ if (theResource is null)
+ throw new InvalidOperationException($"{type} not found for {nameSpace}");
+ return Response.FromValue(theResource.Locations.Select(l => new AzureLocation(l)), resourcePageableProviderResponse.GetRawResponse());
+ }
+
+ ///
+ /// Lists all available geo-locations.
+ ///
+ /// A token to allow the caller to cancel the call to the service. The default value is .
+ /// A collection of location that may take multiple service requests to iterate over.
+ [ForwardsClientCalls]
+ public virtual async Task>> GetAvailableLocationsAsync(CancellationToken cancellationToken = default)
+ {
+ string nameSpace = Id.ResourceType.Namespace;
+ string type = Id.ResourceType.Type;
+ Response resourcePageableProviderResponse = await Client.GetTenantResourceProviderAsync(nameSpace, null, cancellationToken).ConfigureAwait(false);
+ TenantResourceProvider resourcePageableProvider = resourcePageableProviderResponse.Value;
+ if (resourcePageableProvider is null)
+ throw new InvalidOperationException($"{type} not found for {nameSpace}");
+ var theResource = resourcePageableProvider.ResourceTypes.FirstOrDefault(r => type.Equals(r.ResourceType, StringComparison.Ordinal));
+ if (theResource is null)
+ throw new InvalidOperationException($"{type} not found for {nameSpace}");
+ return Response.FromValue(theResource.Locations.Select(l => new AzureLocation(l)), resourcePageableProviderResponse.GetRawResponse());
+ }
+
+ ///
+ /// Gets a cached client to use for extension methods.
+ ///
+ /// The type of client to get.
+ /// The constructor factory for the client.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public virtual T GetCachedClient(Func clientFactory)
+ where T : class
+ {
+ return _clientCache.GetOrAdd(typeof(T), (type) => { return clientFactory(Client); }) as T;
+ }
+
+ ///
+ /// Checks to see if the TagResource API is deployed in the current environment.
+ ///
+ protected virtual bool CanUseTagResource(CancellationToken cancellationToken = default) => Client.CanUseTagResource(cancellationToken);
+
+ ///
+ /// Checks to see if the TagResource API is deployed in the current environment.
+ ///
+ protected virtual Task CanUseTagResourceAsync(CancellationToken cancellationToken = default) => Client.CanUseTagResourceAsync(cancellationToken);
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Assets/Profile/2020-09-01-hybrid.json b/tests/dotnet/dotnet-aot-compat/after/Assets/Profile/2020-09-01-hybrid.json
new file mode 100644
index 0000000000..d19b2f0667
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Assets/Profile/2020-09-01-hybrid.json
@@ -0,0 +1,678 @@
+{
+ "info": {
+ "name": "2020-09-01-hybrid",
+ "description": "Profile definition targeted for hybrid applications that could run on azure stack general availability version and azure cloud for 2010."
+ },
+ "resource-manager": {
+ "microsoft.authorization": {
+ "2016-09-01": [
+ {
+ "resourceType": "locks",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Authorization/stable/2016-09-01/locks.json"
+ }
+ ],
+ "2016-12-01": [
+ {
+ "resourceType": "policyAssignments",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Authorization/stable/2016-12-01/policyAssignments.json"
+ },
+ {
+ "resourceType": "policyDefinitions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Authorization/stable/2016-12-01/policyDefinitions.json"
+ }
+ ],
+ "2015-07-01": [
+ {
+ "resourceType": "permissions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/authorization/resource-manager/Microsoft.Authorization/stable/2015-07-01/authorization-ClassicAdminCalls.json"
+ },
+ {
+ "resourceType": "roleAssignments",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/authorization/resource-manager/Microsoft.Authorization/stable/2015-07-01/authorization-RoleAssignmentsCalls.json"
+ },
+ {
+ "resourceType": "roleDefinitions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/authorization/resource-manager/Microsoft.Authorization/stable/2015-07-01/authorization-RoleDefinitionsCalls.json"
+ },
+ {
+ "resourceType": "providerOperations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/authorization/resource-manager/Microsoft.Authorization/stable/2015-07-01/authorization-ProviderOperationsCalls.json"
+ }
+ ]
+ },
+ "microsoft.commerce": {
+ "2015-06-01-preview": [
+ {
+ "resourceType": "estimateResourceSpend",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/commerce/resource-manager/Microsoft.Commerce/preview/2015-06-01-preview/commerce.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/commerce/resource-manager/Microsoft.Commerce/preview/2015-06-01-preview/commerce.json"
+ },
+ {
+ "resourceType": "subscriberUsageAggregates",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/commerce/resource-manager/Microsoft.Commerce/preview/2015-06-01-preview/commerce.json"
+ },
+ {
+ "resourceType": "usageAggregates",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/commerce/resource-manager/Microsoft.Commerce/preview/2015-06-01-preview/commerce.json"
+ }
+ ]
+ },
+ "microsoft.compute": {
+ "2020-06-01": [
+ {
+ "resourceType": "availabilitySets",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "images",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "locations/publishers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "locations/operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "locations/usages",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "locations/vmSizes",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachines",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachines/extensions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/extensions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualmachineScaleSets/networkInterfaces",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/virtualMachines",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ },
+ {
+ "resourceType": "virtualMachineScaleSets/virtualMachines/networkInterfaces",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2020-06-01/compute.json"
+ }
+ ],
+ "2019-07-01": [
+ {
+ "resourceType": "disks",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2019-07-01/disk.json"
+ },
+ {
+ "resourceType": "snapshots",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/compute/resource-manager/Microsoft.Compute/stable/2019-07-01/disk.json"
+ }
+ ]
+ },
+ "microsoft.databoxedge": {
+ "2019-08-01": [
+ {
+ "resourceType": "dataBoxEdgeDevices",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/databoxedge/resource-manager/Microsoft.DataBoxEdge/stable/2019-08-01/databoxedge.json"
+ },
+ {
+ "resourceType": "dataBoxEdgeDevices/checkNameAvailability",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/databoxedge/resource-manager/Microsoft.DataBoxEdge/stable/2019-08-01/databoxedge.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/databoxedge/resource-manager/Microsoft.DataBoxEdge/stable/2019-08-01/databoxedge.json"
+ }
+ ]
+ },
+ "microsoft.devices": {
+ "2019-07-01-preview": [
+ {
+ "resourceType": "usages",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "locations/quotas",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "locations/skus",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "checkNameAvailability",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "operationResults",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "IotHubs",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "backupProviders",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ },
+ {
+ "resourceType": "backupProviders/operationResults",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/iothub/resource-manager/Microsoft.Devices/preview/2019-07-01-preview/iothub.json"
+ }
+ ]
+ },
+ "microsoft.eventhubs": {
+ "2018-01-01-preview": [
+ {
+ "resourceType": "availableClusterRegions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/preview/2018-01-01-preview/AvailableClusterRegions-preview.json"
+ },
+ {
+ "resourceType": "clusters",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/preview/2018-01-01-preview/Clusters-preview.json"
+ },
+ {
+ "resourceType": "namespaces",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/preview/2018-01-01-preview/namespaces-preview.json"
+ }
+ ],
+ "2017-04-01": [
+ {
+ "resourceType": "checkNameAvailability",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/CheckNameAvailability.json"
+ },
+ {
+ "resourceType": "namespaces/authorizationRules",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/AuthorizationRules.json"
+ },
+ {
+ "resourceType": "namespaces/eventhubs",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/eventhubs.json"
+ },
+ {
+ "resourceType": "namespaces/eventhubs/authorizationRules",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/AuthorizationRules.json"
+ },
+ {
+ "resourceType": "namespaces/eventhubs/consumerGroups",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/consumergroups.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/operations.json"
+ },
+ {
+ "resourceType": "sku",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/eventhub/resource-manager/Microsoft.EventHub/stable/2017-04-01/sku.json"
+ }
+ ]
+ },
+ "microsoft.insights": {
+ "2018-01-01": [
+ {
+ "resourceType": "metricDefinitions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/stable/2018-01-01/metricDefinitions_API.json"
+ },
+ {
+ "resourceType": "metrics",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/stable/2018-01-01/metrics_API.json"
+ }
+ ],
+ "2017-05-01-preview": [
+ {
+ "resourceType": "diagnosticSettings",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/preview/2017-05-01-preview/diagnosticsSettings_API.json"
+ },
+ {
+ "resourceType": "diagnosticSettingCategories",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/preview/2017-05-01-preview/diagnosticsSettingsCategories_API.json"
+ }
+ ],
+ "2015-04-01": [
+ {
+ "resourceType": "eventCategories",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/stable/2015-04-01/eventCategories_API.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/monitor/resource-manager/Microsoft.Insights/stable/2015-04-01/operations_API.json"
+ }
+ ]
+ },
+ "microsoft.keyvault": {
+ "2019-09-01": [
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2019-09-01/providers.json"
+ },
+ {
+ "resourceType": "vaults",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2019-09-01/keyvault.json"
+ },
+ {
+ "resourceType": "vaults/accessPolicies",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2019-09-01/keyvault.json"
+ },
+ {
+ "resourceType": "vaults/secrets",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/keyvault/resource-manager/Microsoft.KeyVault/stable/2019-09-01/secrets.json"
+ }
+ ]
+ },
+ "microsoft.network": {
+ "2018-11-01": [
+ {
+ "resourceType": "connections",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/virtualNetworkGateway.json"
+ },
+ {
+ "resourceType": "loadBalancers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/loadBalancer.json"
+ },
+ {
+ "resourceType": "localNetworkGateways",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/virtualNetworkGateway.json"
+ },
+ {
+ "resourceType": "locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/network.json"
+ },
+ {
+ "resourceType": "locations/operationResults",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/network.json"
+ },
+ {
+ "resourceType": "locations/operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/network.json"
+ },
+ {
+ "resourceType": "locations/usages",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/network.json"
+ },
+ {
+ "resourceType": "networkInterfaces",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/networkInterface.json"
+ },
+ {
+ "resourceType": "networkSecurityGroups",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/networkSecurityGroup.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/operation.json"
+ },
+ {
+ "resourceType": "publicIpAddresses",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/publicIpAddress.json"
+ },
+ {
+ "resourceType": "routeTables",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/routeTable.json"
+ },
+ {
+ "resourceType": "virtualNetworkGateways",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/virtualNetworkGateway.json"
+ },
+ {
+ "resourceType": "virtualNetworks",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/network/resource-manager/Microsoft.Network/stable/2018-11-01/virtualNetwork.json"
+ }
+ ],
+ "2016-04-01": [
+ {
+ "resourceType": "dnsZones",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/dns/resource-manager/Microsoft.Network/stable/2016-04-01/dns.json"
+ }
+ ]
+ },
+ "microsoft.resources": {
+ "2016-06-01": [
+ {
+ "resourceType": "subscriptions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2016-06-01/subscriptions.json"
+ },
+ {
+ "resourceType": "subscriptions/locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2016-06-01/subscriptions.json"
+ },
+ {
+ "resourceType": "tenants",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2016-06-01/subscriptions.json"
+ }
+ ],
+ "2019-10-01": [
+ {
+ "resourceType": "deployments",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "deployments/operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "links",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "providers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "resourceGroups",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "resources",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/operationresults",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/providers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/resourceGroups",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/resourceGroups/resources",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/resources",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/tagNames",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ },
+ {
+ "resourceType": "subscriptions/tagNames/tagValues",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/resources/resource-manager/Microsoft.Resources/stable/2019-10-01/resources.json"
+ }
+ ]
+ },
+ "microsoft.storage": {
+ "2019-06-01": [
+ {
+ "resourceType": "checkNameAvailability",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "locations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "locations/quotas",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "storageAccounts",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "storageAccounts/blobServices",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "storageAccounts/queueServices",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "storageAccounts/tableServices",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ },
+ {
+ "resourceType": "usages",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/storage/resource-manager/Microsoft.Storage/stable/2019-06-01/storage.json"
+ }
+ ]
+ },
+ "microsoft.web": {
+ "2018-02-01": [
+ {
+ "resourceType": "certificates",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/Certificates.json"
+ },
+ {
+ "resourceType": "operations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "checknameavailability",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "metadata",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/domainOwnershipIdentifiers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/extensions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/hostNameBindings",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/instances",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/instances/extensions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/slots",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/slots/hostNameBindings",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/slots/instances",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "sites/slots/instances/extensions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "serverFarms",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/WebApps.json"
+ },
+ {
+ "resourceType": "serverFarms/metricDefinitions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/AppServicePlans.json"
+ },
+ {
+ "resourceType": "serverFarms/metrics",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/AppServicePlans.json"
+ },
+ {
+ "resourceType": "serverFarms/usages",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/AppServicePlans.json"
+ },
+ {
+ "resourceType": "availableStacks",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/Provider.json"
+ },
+ {
+ "resourceType": "deploymentLocations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "georegions",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "listSitesAssignedToHostName",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "publishingUsers",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "recommendations",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/Recommendations.json"
+ },
+ {
+ "resourceType": "sourceControls",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ },
+ {
+ "resourceType": "validate",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/web/resource-manager/Microsoft.Web/stable/2018-02-01/ResourceProvider.json"
+ }
+ ]
+ },
+ "microsoft.containerregistry" : {
+ "2019-05-01": [
+ {
+ "resourceType": "registries",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/importImage",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/webhooks",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/webhooks/ping",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/webhooks/getCallbackConfig",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/webhooks/listEvents",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/listCredentials",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "registries/regenerateCredential",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "checkNameAvailability",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ },
+ {
+ "resourceType": "operations",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/resource-manager/Microsoft.ContainerRegistry/stable/2019-05-01/containerregistry.json"
+ }
+ ]
+ },
+ "microsoft.containerservice" : {
+ "2020-11-01": [
+ {
+ "resourceType": "managedclusters",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerservice/resource-manager/Microsoft.ContainerService/stable/2020-11-01/managedClusters.json"
+ }
+ ],
+ "2019-04-01": [
+ {
+ "resourceType": "locations/orchestrators",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerservice/resource-manager/Microsoft.ContainerService/stable/2019-04-01/location.json"
+ }
+ ],
+ "2017-07-01": [
+ {
+ "resourceType": "containerServices",
+ "path" : "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerservice/resource-manager/Microsoft.ContainerService/stable/2017-07-01/containerService.json"
+ }
+ ]
+ }
+ },
+ "data-plane": {
+ "microsoft.keyvault": {
+ "7.1": [
+ {
+ "resourceType": "secrets",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/secrets.json"
+ },
+ {
+ "resourceType": "keys",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/keyvault/data-plane/Microsoft.KeyVault/stable/7.1/keys.json"
+ }
+ ]
+ },
+ "microsoft.containerregistry": {
+ "2019-08-15-preview": [
+ {
+ "resourceType": "*",
+ "path": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/containerregistry/data-plane/Microsoft.ContainerRegistry/preview/2019-08-15/containerregistry.json"
+ }
+ ]
+ },
+ "microsoft.storage": {
+ "resourceType": "*",
+ "2019-07-07": []
+ }
+ }
+ }
diff --git a/tests/dotnet/dotnet-aot-compat/after/Azure.ResourceManager.csproj b/tests/dotnet/dotnet-aot-compat/after/Azure.ResourceManager.csproj
new file mode 100644
index 0000000000..a8b3ec55de
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Azure.ResourceManager.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net9.0
+ 1.14.0-beta.1
+
+ 1.13.1
+ Azure.ResourceManager
+ Microsoft Azure Resource Manager client SDK for Azure resources.
+ azure;management;resource
+ true
+ false
+ false
+ $(NoWarn);AZPROVISION001;SCM0005
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/dotnet/dotnet-aot-compat/after/AzureStackProfile.cs b/tests/dotnet/dotnet-aot-compat/after/AzureStackProfile.cs
new file mode 100644
index 0000000000..09f285c061
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/AzureStackProfile.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// AzureStackProfile represents the information of an Azure Stack profile.
+ ///
+ public enum AzureStackProfile
+ {
+ /// The 2020-09-01-hybrid profile.
+ Profile20200901Hybrid
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/BicepModelReaderWriterOptions.cs b/tests/dotnet/dotnet-aot-compat/after/BicepModelReaderWriterOptions.cs
new file mode 100644
index 0000000000..eaa886e500
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/BicepModelReaderWriterOptions.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// Provides the options for reading and writing Bicep.
+ ///
+ [Experimental("AZPROVISION001")]
+ public class BicepModelReaderWriterOptions : ModelReaderWriterOptions
+ {
+ ///
+ /// Initializes a new instance of .
+ ///
+ public BicepModelReaderWriterOptions() : base("bicep")
+ {
+ }
+
+ ///
+ /// The set of property overrides to apply when writing the bicep. The key of the dictionary corresponds to the
+ /// instance being written, and the value is a dictionary of property names to property values.
+ ///
+ public IDictionary> PropertyOverrides { get; } = new Dictionary>();
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/CodeGenAttributes.cs b/tests/dotnet/dotnet-aot-compat/after/CodeGenAttributes.cs
new file mode 100644
index 0000000000..efc951c129
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/CodeGenAttributes.cs
@@ -0,0 +1,65 @@
+// Stubs for Azure AutoRest codegen types (not available as a public NuGet package)
+#nullable enable
+
+// GeneratorPageableHelpers is a codegen-emitted copy of PageableHelpers
+namespace Azure.Core
+{
+ internal static class GeneratorPageableHelpers
+ {
+ public static AsyncPageable CreateAsyncPageable(
+ System.Func? createFirstPageRequest,
+ System.Func? createNextPageRequest,
+ System.Func valueFactory,
+ Pipeline.ClientDiagnostics clientDiagnostics,
+ Pipeline.HttpPipeline pipeline,
+ string scopeName,
+ string? itemPropertyName,
+ string? nextLinkPropertyName,
+ System.Threading.CancellationToken cancellationToken) where T : notnull
+ => PageableHelpers.CreateAsyncPageable(createFirstPageRequest, createNextPageRequest, valueFactory, clientDiagnostics, pipeline, scopeName, itemPropertyName, nextLinkPropertyName, cancellationToken);
+
+ public static Pageable CreatePageable(
+ System.Func? createFirstPageRequest,
+ System.Func? createNextPageRequest,
+ System.Func valueFactory,
+ Pipeline.ClientDiagnostics clientDiagnostics,
+ Pipeline.HttpPipeline pipeline,
+ string scopeName,
+ string? itemPropertyName,
+ string? nextLinkPropertyName,
+ System.Threading.CancellationToken cancellationToken) where T : notnull
+ => PageableHelpers.CreatePageable(createFirstPageRequest, createNextPageRequest, valueFactory, clientDiagnostics, pipeline, scopeName, itemPropertyName, nextLinkPropertyName, cancellationToken);
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct)]
+ internal class CodeGenTypeAttribute : System.Attribute
+ {
+ public CodeGenTypeAttribute(string originalName) { }
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = true)]
+ internal class CodeGenSuppressAttribute : System.Attribute
+ {
+ public CodeGenSuppressAttribute(string member, params System.Type[] parameters) { }
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple = true)]
+ internal class CodeGenSuppressTypeAttribute : System.Attribute
+ {
+ public CodeGenSuppressTypeAttribute(string typeName) { }
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = true)]
+ internal class CodeGenMemberAttribute : System.Attribute
+ {
+ public CodeGenMemberAttribute(string originalName) { }
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = true)]
+ internal class CodeGenSerializationAttribute : System.Attribute
+ {
+ public CodeGenSerializationAttribute(string propertyName) { }
+ public string? SerializationValueHook { get; set; }
+ public string? DeserializationValueHook { get; set; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmPlan.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmPlan.cs
new file mode 100644
index 0000000000..35564305f8
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmPlan.cs
@@ -0,0 +1,95 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ ///
+ /// Representation of a publisher plan for marketplace RPs.
+ ///
+ public sealed partial class ArmPlan : IEquatable
+ {
+ ///
+ /// Compares this instance with another object and determines if they are equals.
+ ///
+ /// object to compare.
+ /// True if they are equals, otherwise false.
+ public bool Equals(ArmPlan other)
+ {
+ if (ReferenceEquals(other, null))
+ return false;
+
+ if (ReferenceEquals(this, other))
+ return true;
+
+ return string.Equals(Name, other.Name, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(Product, other.Product, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(PromotionCode, other.PromotionCode, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(Publisher, other.Publisher, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(Version, other.Version, StringComparison.InvariantCultureIgnoreCase);
+ }
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(obj, null))
+ {
+ return false;
+ }
+
+ if (obj is not ArmPlan other)
+ return false;
+
+ return Equals(other);
+ }
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode()
+ {
+ return HashCodeBuilder.Combine(
+ Name?.ToLower(CultureInfo.InvariantCulture),
+ Publisher?.ToLower(CultureInfo.InvariantCulture),
+ Product?.ToLower(CultureInfo.InvariantCulture),
+ PromotionCode?.ToLower(CultureInfo.InvariantCulture),
+ Version?.ToLower(CultureInfo.InvariantCulture));
+ }
+
+ ///
+ /// Compares this instance with another object and determines if they are equals.
+ ///
+ /// The object on the left side of the operator.
+ /// The object on the right side of the operator.
+ /// True if they are equal, otherwise false.
+ public static bool operator ==(ArmPlan left, ArmPlan right)
+ {
+ if (ReferenceEquals(left, null))
+ {
+ return ReferenceEquals(right, null);
+ }
+
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares this instance with another object and determines if they are equals.
+ ///
+ /// The object on the left side of the operator.
+ /// The object on the right side of the operator.
+ /// True if they are not equal, otherwise false.
+ public static bool operator !=(ArmPlan left, ArmPlan right)
+ {
+ return !(left == right);
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmSku.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmSku.cs
new file mode 100644
index 0000000000..ce20416eb1
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ArmSku.cs
@@ -0,0 +1,95 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ ///
+ /// A class representing SKU for resource.
+ ///
+ public sealed partial class ArmSku : IEquatable
+ {
+ ///
+ /// Compares this instance with another object and determines if they are equals.
+ ///
+ /// object to compare.
+ /// True if they are equals, otherwise false.
+ public bool Equals(ArmSku other)
+ {
+ if (other == null)
+ return false;
+
+ if (object.ReferenceEquals(this, other))
+ return true;
+
+ return string.Equals(Name, other.Name, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(Family, other.Family, StringComparison.InvariantCultureIgnoreCase) &&
+ string.Equals(Size, other.Size, StringComparison.InvariantCultureIgnoreCase) &&
+ (Tier.HasValue ? Tier.Value.Equals(other.Tier) : !other.Tier.HasValue) &&
+ long.Equals(Capacity, other.Capacity);
+ }
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(this, obj))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(obj, null))
+ {
+ return false;
+ }
+
+ if (obj is not ArmSku other)
+ return false;
+
+ return Equals(other);
+ }
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode()
+ {
+ return HashCodeBuilder.Combine(
+ Name?.ToLower(CultureInfo.InvariantCulture),
+ Family?.ToLower(CultureInfo.InvariantCulture),
+ Size?.ToLower(CultureInfo.InvariantCulture),
+ Tier?.ToString().ToLower(CultureInfo.InvariantCulture),
+ Capacity);
+ }
+
+ ///
+ /// Compares this instance with another object and determines if they are equals.
+ ///
+ /// The sku on the left side of the operator.
+ /// The sku on the right side of the operator.
+ /// True if they are equal, otherwise false.
+ public static bool operator ==(ArmSku left, ArmSku right)
+ {
+ if (ReferenceEquals(left, null))
+ {
+ return ReferenceEquals(right, null);
+ }
+
+ return left.Equals(right);
+ }
+
+ ///
+ /// Compares this instance with another object and determines if they are not equal.
+ ///
+ /// The sku on the left side of the operator.
+ /// The sku on the right side of the operator.
+ /// True if they are not equal, otherwise false.
+ public static bool operator !=(ArmSku left, ArmSku right)
+ {
+ return !(left == right);
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionProperties.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionProperties.cs
new file mode 100644
index 0000000000..a5a35be565
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionProperties.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ // this class here is to keep the class public and add the EditorBrowsableNever attribute
+ // this class is exposed in resourcemanager by accident, now we hide it in resourcemanager
+ [Obsolete("This type is obsolete and will be removed in a future release.", false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public partial class EncryptionProperties
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionStatus.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionStatus.cs
new file mode 100644
index 0000000000..c1fc8e2bbc
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/EncryptionStatus.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ // this class here is to keep the class public and add the EditorBrowsableNever attribute
+ // this class is exposed in resourcemanager by accident, now we hide it in resourcemanager
+ [Obsolete("This type is obsolete and will be removed in a future release.", false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public readonly partial struct EncryptionStatus
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/KeyVaultProperties.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/KeyVaultProperties.cs
new file mode 100644
index 0000000000..5b49b0341a
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/KeyVaultProperties.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ // this class here is to keep the class public and add the EditorBrowsableNever attribute
+ // this class is exposed in resourcemanager by accident, now we hide it in resourcemanager
+ [Obsolete("This type is obsolete and will be removed in a future release.", false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public partial class KeyVaultProperties
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.Serialization.cs
new file mode 100644
index 0000000000..cbc31f23a0
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.Serialization.cs
@@ -0,0 +1,263 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+using Azure.ResourceManager.Models;
+
+[assembly: CodeGenSuppressType("ManagedServiceIdentity")]
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(ManagedServiceIdentityConverter))]
+ public partial class ManagedServiceIdentity : IJsonModel
+ {
+ internal void Write(Utf8JsonWriter writer, ModelReaderWriterOptions options, JsonSerializerOptions jOptions = null)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ManagedServiceIdentity)} does not support '{format}' format.");
+ }
+
+ writer.WriteStartObject();
+ JsonSerializer.Serialize(writer, ManagedServiceIdentityType, ResourceManagerJsonContext.Default.ManagedServiceIdentityType);
+ if (options.Format != "W" && Optional.IsDefined(PrincipalId))
+ {
+ writer.WritePropertyName("principalId"u8);
+ writer.WriteStringValue(PrincipalId.Value);
+ }
+ if (options.Format != "W" && Optional.IsDefined(TenantId))
+ {
+ writer.WritePropertyName("tenantId"u8);
+ writer.WriteStringValue(TenantId.Value);
+ }
+ if (Optional.IsCollectionDefined(UserAssignedIdentities))
+ {
+ writer.WritePropertyName("userAssignedIdentities"u8);
+ writer.WriteStartObject();
+ foreach (var item in UserAssignedIdentities)
+ {
+ writer.WritePropertyName(item.Key);
+ JsonSerializer.Serialize(writer, item.Value, ResourceManagerJsonContext.Default.UserAssignedIdentity);
+ }
+ writer.WriteEndObject();
+ }
+ writer.WriteEndObject();
+ }
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ Write(writer, options, null);
+ }
+
+ ManagedServiceIdentity IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ManagedServiceIdentity)} does not support '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeManagedServiceIdentity(document.RootElement, options);
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(ManagedServiceIdentity)} does not support '{options.Format}' format.");
+ }
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(ManagedServiceIdentityType), out propertyOverride);
+ if (Optional.IsDefined(ManagedServiceIdentityType) || hasPropertyOverride)
+ {
+ builder.Append(" type:");
+ if (hasPropertyOverride)
+ {
+ builder.AppendLine($" {propertyOverride}");
+ }
+ else
+ {
+ builder.AppendLine($" '{ManagedServiceIdentityType}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(UserAssignedIdentities), out propertyOverride);
+ if (UserAssignedIdentities.Any() || hasPropertyOverride)
+ {
+ builder.Append(" userAssignedIdentities:");
+ builder.AppendLine(" {");
+ if (hasPropertyOverride)
+ {
+ builder.AppendLine($" {propertyOverride}");
+ }
+ else
+ {
+ foreach (var item in UserAssignedIdentities)
+ {
+ builder.Append($" {item.Key}:");
+ AppendChildObject(builder, item.Value, options, 4, false);
+ }
+ }
+
+ builder.AppendLine(" }");
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ private void AppendChildObject(StringBuilder stringBuilder, object childObject, ModelReaderWriterOptions options, int spaces, bool indentFirstLine)
+ {
+ string indent = new string(' ', spaces);
+ BinaryData data = ModelReaderWriter.Write(childObject, options, AzureResourceManagerContext.Default);
+ string[] lines = data.ToString().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+ bool inMultilineString = false;
+ for (int i = 0; i < lines.Length; i++)
+ {
+ string line = lines[i];
+ if (inMultilineString)
+ {
+ if (line.Contains("'''"))
+ {
+ inMultilineString = false;
+ }
+ stringBuilder.AppendLine(line);
+ continue;
+ }
+ if (line.Contains("'''"))
+ {
+ inMultilineString = true;
+ stringBuilder.AppendLine($"{indent}{line}");
+ continue;
+ }
+ if (i == 0 && !indentFirstLine)
+ {
+ stringBuilder.AppendLine($" {line}");
+ }
+ else
+ {
+ stringBuilder.AppendLine($"{indent}{line}");
+ }
+ }
+ }
+
+ internal static ManagedServiceIdentity DeserializeManagedServiceIdentity(JsonElement element, ModelReaderWriterOptions options, JsonSerializerOptions jOptions)
+ {
+ options ??= new ModelReaderWriterOptions("W");
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ Guid? principalId = default;
+ Guid? tenantId = default;
+ ManagedServiceIdentityType type = default;
+ IDictionary userAssignedIdentities = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("principalId"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null || property.Value.GetString().Length == 0)
+ {
+ continue;
+ }
+ principalId = property.Value.GetGuid();
+ continue;
+ }
+ if (property.NameEquals("tenantId"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null || property.Value.GetString().Length == 0)
+ {
+ continue;
+ }
+ tenantId = property.Value.GetGuid();
+ continue;
+ }
+ if (property.NameEquals("type"u8))
+ {
+ type = JsonSerializer.Deserialize($"{{{property}}}", ResourceManagerJsonContext.Default.ManagedServiceIdentityType);
+ continue;
+ }
+ if (property.NameEquals("userAssignedIdentities"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ Dictionary dictionary = new Dictionary();
+ foreach (var property0 in property.Value.EnumerateObject())
+ {
+ dictionary.Add(new ResourceIdentifier(property0.Name), JsonSerializer.Deserialize(property0.Value.GetRawText(), ResourceManagerJsonContext.Default.UserAssignedIdentity));
+ }
+ userAssignedIdentities = dictionary;
+ continue;
+ }
+ }
+ return new ManagedServiceIdentity(principalId, tenantId, type, userAssignedIdentities ?? new ChangeTrackingDictionary());
+ }
+
+ internal static ManagedServiceIdentity DeserializeManagedServiceIdentity(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ return DeserializeManagedServiceIdentity(element, options, null);
+ }
+
+ ManagedServiceIdentity IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data);
+ return DeserializeManagedServiceIdentity(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ManagedServiceIdentity)} does not support '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class ManagedServiceIdentityConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, ManagedServiceIdentity model, JsonSerializerOptions options)
+ {
+ model.Write(writer, new ModelReaderWriterOptions("W"), options);
+ }
+ public override ManagedServiceIdentity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeManagedServiceIdentity(document.RootElement, null, options);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.cs
new file mode 100644
index 0000000000..96313186cf
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentity.cs
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Managed service identity (system assigned and/or user assigned identities).
+ [PropertyReferenceType(new string[] { "UserAssignedIdentities" })]
+ public partial class ManagedServiceIdentity
+ {
+ /// Initializes a new instance of ManagedServiceIdentity.
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ [InitializationConstructor]
+ public ManagedServiceIdentity(ManagedServiceIdentityType managedServiceIdentityType)
+ {
+ ManagedServiceIdentityType = managedServiceIdentityType;
+ UserAssignedIdentities = new ChangeTrackingDictionary();
+ }
+
+ /// Initializes a new instance of ManagedServiceIdentity.
+ /// The service principal ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// The tenant ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ /// The set of user assigned identities associated with the resource. The userAssignedIdentities dictionary keys will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}. The dictionary values can be empty objects ({}) in requests.
+ [SerializationConstructor]
+ internal ManagedServiceIdentity(Guid? principalId, Guid? tenantId, ManagedServiceIdentityType managedServiceIdentityType, IDictionary userAssignedIdentities)
+ {
+ PrincipalId = principalId;
+ TenantId = tenantId;
+ ManagedServiceIdentityType = managedServiceIdentityType;
+ UserAssignedIdentities = userAssignedIdentities;
+ }
+
+ /// The service principal ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ public Guid? PrincipalId { get; }
+ /// The tenant ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ public Guid? TenantId { get; }
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ public ManagedServiceIdentityType ManagedServiceIdentityType { get; set; }
+ /// The set of user assigned identities associated with the resource. The userAssignedIdentities dictionary keys will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}. The dictionary values can be empty objects ({}) in requests.
+ public IDictionary UserAssignedIdentities { get; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentityType.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentityType.cs
new file mode 100644
index 0000000000..7954ef73df
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/ManagedServiceIdentityType.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ [JsonConverter(typeof(ManagedServiceIdentityTypeConverter))]
+ public readonly partial struct ManagedServiceIdentityType : IEquatable
+ {
+ internal partial class ManagedServiceIdentityTypeConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, ManagedServiceIdentityType model, JsonSerializerOptions options)
+ {
+ writer.WritePropertyName("type");
+ writer.WriteStringValue(model.ToString());
+ }
+ public override ManagedServiceIdentityType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ foreach (var property in document.RootElement.EnumerateObject())
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ return default;
+ else
+ return new ManagedServiceIdentityType(property.Value.GetString());
+ }
+ return null;
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentity.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentity.cs
new file mode 100644
index 0000000000..e887668292
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentity.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Managed service identity (either system assigned, or none).
+ // this class is consolidated into the ManagedServiceIdentity class.
+ [Obsolete("This type is obsolete and will be removed in a future release.", false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public partial class SystemAssignedServiceIdentity
+ {
+ /// Initializes a new instance of SystemAssignedServiceIdentity.
+ /// Type of managed service identity (either system assigned, or none).
+ [InitializationConstructor]
+ public SystemAssignedServiceIdentity(SystemAssignedServiceIdentityType systemAssignedServiceIdentityType)
+ {
+ Identity = new ManagedServiceIdentity(systemAssignedServiceIdentityType.ToString());
+ }
+
+ /// Initializes a new instance of SystemAssignedServiceIdentity.
+ /// The service principal ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// The tenant ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// Type of managed service identity (either system assigned, or none).
+ [SerializationConstructor]
+ internal SystemAssignedServiceIdentity(Guid? principalId, Guid? tenantId, SystemAssignedServiceIdentityType systemAssignedServiceIdentityType)
+ {
+ Identity = new ManagedServiceIdentity(principalId, tenantId, systemAssignedServiceIdentityType.ToString(), null);
+ }
+
+ /// Initializes a new instance of SystemAssignedServiceIdentity by given ManagedServiceIdentity.
+ internal SystemAssignedServiceIdentity(ManagedServiceIdentity managedServiceIdentity)
+ {
+ if (managedServiceIdentity == null)
+ {
+ throw new ArgumentNullException();
+ }
+ Identity = managedServiceIdentity;
+ }
+
+ internal ManagedServiceIdentity Identity { get; set; }
+
+ /// The service principal ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ public Guid? PrincipalId
+ {
+ get => Identity.PrincipalId;
+ }
+ /// The tenant ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ public Guid? TenantId
+ {
+ get => Identity.TenantId;
+ }
+ /// Type of managed service identity (either system assigned, or none).
+ public SystemAssignedServiceIdentityType SystemAssignedServiceIdentityType
+ {
+ get => Identity.ManagedServiceIdentityType.ToString();
+ set => Identity.ManagedServiceIdentityType = value.ToString();
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentityType.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentityType.cs
new file mode 100644
index 0000000000..15fb71110a
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/Models/SystemAssignedServiceIdentityType.cs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ // this struct is consolidated into ManagedServiceIdentityType.
+ [Obsolete("This type is obsolete and will be removed in a future release.", false)]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public readonly partial struct SystemAssignedServiceIdentityType
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Custom/ResourceManagerModelFactory.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/ResourceManagerModelFactory.cs
new file mode 100644
index 0000000000..c5d2b26469
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Custom/ResourceManagerModelFactory.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using Azure.Core;
+using Azure.ResourceManager.Resources.Models;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Model factory for read-only models.
+ public static partial class ResourceManagerModelFactory
+ {
+ /// Initializes a new instance of LocationExpanded.
+ /// The service principal ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// The tenant ID of the system assigned identity. This property will only be provided for a system assigned identity.
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ /// The set of user assigned identities associated with the resource. The userAssignedIdentities dictionary keys will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}. The dictionary values can be empty objects ({}) in requests.
+ /// A new instance for mocking.
+ public static ManagedServiceIdentity ManagedServiceIdentity(Guid? principalId = null, Guid? tenantId = null, ManagedServiceIdentityType managedServiceIdentityType = default, IDictionary userAssignedIdentities = null)
+ {
+ return new ManagedServiceIdentity(principalId, tenantId, managedServiceIdentityType, userAssignedIdentities);
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Argument.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Argument.cs
new file mode 100644
index 0000000000..0e6dfdb59a
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Argument.cs
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Azure.ResourceManager
+{
+ internal static class Argument
+ {
+ public static void AssertNotNull(T value, string name)
+ {
+ if (value is null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ }
+
+ public static void AssertNotNull(T? value, string name)
+ where T : struct
+ {
+ if (!value.HasValue)
+ {
+ throw new ArgumentNullException(name);
+ }
+ }
+
+ public static void AssertNotNullOrEmpty(IEnumerable value, string name)
+ {
+ if (value is null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ if (value is ICollection collectionOfT && collectionOfT.Count == 0)
+ {
+ throw new ArgumentException("Value cannot be an empty collection.", name);
+ }
+ if (value is ICollection collection && collection.Count == 0)
+ {
+ throw new ArgumentException("Value cannot be an empty collection.", name);
+ }
+ using IEnumerator e = value.GetEnumerator();
+ if (!e.MoveNext())
+ {
+ throw new ArgumentException("Value cannot be an empty collection.", name);
+ }
+ }
+
+ public static void AssertNotNullOrEmpty(string value, string name)
+ {
+ if (value is null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ if (value.Length == 0)
+ {
+ throw new ArgumentException("Value cannot be an empty string.", name);
+ }
+ }
+
+ public static void AssertNotNullOrWhiteSpace(string value, string name)
+ {
+ if (value is null)
+ {
+ throw new ArgumentNullException(name);
+ }
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ throw new ArgumentException("Value cannot be empty or contain only white-space characters.", name);
+ }
+ }
+
+ public static void AssertNotDefault(ref T value, string name)
+ where T : struct, IEquatable
+ {
+ if (value.Equals(default))
+ {
+ throw new ArgumentException("Value cannot be empty.", name);
+ }
+ }
+
+ public static void AssertInRange(T value, T minimum, T maximum, string name)
+ where T : notnull, IComparable
+ {
+ if (minimum.CompareTo(value) > 0)
+ {
+ throw new ArgumentOutOfRangeException(name, "Value is less than the minimum allowed.");
+ }
+ if (maximum.CompareTo(value) < 0)
+ {
+ throw new ArgumentOutOfRangeException(name, "Value is greater than the maximum allowed.");
+ }
+ }
+
+ public static void AssertEnumDefined(Type enumType, object value, string name)
+ {
+ if (!Enum.IsDefined(enumType, value))
+ {
+ throw new ArgumentException($"Value not defined for {enumType.FullName}.", name);
+ }
+ }
+
+ public static T CheckNotNull(T value, string name)
+ where T : class
+ {
+ AssertNotNull(value, name);
+ return value;
+ }
+
+ public static string CheckNotNullOrEmpty(string value, string name)
+ {
+ AssertNotNullOrEmpty(value, name);
+ return value;
+ }
+
+ public static void AssertNull(T value, string name, string message = null)
+ {
+ if (value != null)
+ {
+ throw new ArgumentException(message ?? "Value must be null.", name);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/BicepSerializationHelpers.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/BicepSerializationHelpers.cs
new file mode 100644
index 0000000000..633bf5b166
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/BicepSerializationHelpers.cs
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Text;
+
+namespace Azure.ResourceManager
+{
+ internal static class BicepSerializationHelpers
+ {
+ public static void AppendChildObject(StringBuilder stringBuilder, object childObject, ModelReaderWriterOptions options, int spaces, bool indentFirstLine, string formattedPropertyName)
+ {
+ string indent = new string(' ', spaces);
+ int emptyObjectLength = 2 + spaces + Environment.NewLine.Length + Environment.NewLine.Length;
+ int length = stringBuilder.Length;
+ bool inMultilineString = false;
+
+ BinaryData data = ModelReaderWriter.Write(childObject, options, AzureResourceManagerContext.Default);
+ string[] lines = data.ToString().Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
+ for (int i = 0; i < lines.Length; i++)
+ {
+ string line = lines[i];
+ if (inMultilineString)
+ {
+ if (line.Contains("'''"))
+ {
+ inMultilineString = false;
+ }
+ stringBuilder.AppendLine(line);
+ continue;
+ }
+ if (line.Contains("'''"))
+ {
+ inMultilineString = true;
+ stringBuilder.AppendLine($"{indent}{line}");
+ continue;
+ }
+ if (i == 0 && !indentFirstLine)
+ {
+ stringBuilder.AppendLine($"{line}");
+ }
+ else
+ {
+ stringBuilder.AppendLine($"{indent}{line}");
+ }
+ }
+ if (stringBuilder.Length == length + emptyObjectLength)
+ {
+ stringBuilder.Length = stringBuilder.Length - emptyObjectLength - formattedPropertyName.Length;
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingDictionary.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingDictionary.cs
new file mode 100644
index 0000000000..3e0457dd83
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingDictionary.cs
@@ -0,0 +1,167 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Azure.ResourceManager
+{
+ internal class ChangeTrackingDictionary : IDictionary, IReadOnlyDictionary where TKey : notnull
+ {
+ private IDictionary _innerDictionary;
+
+ public ChangeTrackingDictionary()
+ {
+ }
+
+ public ChangeTrackingDictionary(IDictionary dictionary)
+ {
+ if (dictionary == null)
+ {
+ return;
+ }
+ _innerDictionary = new Dictionary(dictionary);
+ }
+
+ public ChangeTrackingDictionary(IReadOnlyDictionary dictionary)
+ {
+ if (dictionary == null)
+ {
+ return;
+ }
+ _innerDictionary = new Dictionary();
+ foreach (var pair in dictionary)
+ {
+ _innerDictionary.Add(pair);
+ }
+ }
+
+ public bool IsUndefined => _innerDictionary == null;
+
+ public int Count => IsUndefined ? 0 : EnsureDictionary().Count;
+
+ public bool IsReadOnly => IsUndefined ? false : EnsureDictionary().IsReadOnly;
+
+ public ICollection Keys => IsUndefined ? Array.Empty() : EnsureDictionary().Keys;
+
+ public ICollection Values => IsUndefined ? Array.Empty() : EnsureDictionary().Values;
+
+ public TValue this[TKey key]
+ {
+ get
+ {
+ if (IsUndefined)
+ {
+ throw new KeyNotFoundException(nameof(key));
+ }
+ return EnsureDictionary()[key];
+ }
+ set
+ {
+ EnsureDictionary()[key] = value;
+ }
+ }
+
+ IEnumerable IReadOnlyDictionary.Keys => Keys;
+
+ IEnumerable IReadOnlyDictionary.Values => Values;
+
+ public IEnumerator> GetEnumerator()
+ {
+ if (IsUndefined)
+ {
+ IEnumerator> enumerateEmpty()
+ {
+ yield break;
+ }
+ return enumerateEmpty();
+ }
+ return EnsureDictionary().GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public void Add(KeyValuePair item)
+ {
+ EnsureDictionary().Add(item);
+ }
+
+ public void Clear()
+ {
+ EnsureDictionary().Clear();
+ }
+
+ public bool Contains(KeyValuePair item)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureDictionary().Contains(item);
+ }
+
+ public void CopyTo(KeyValuePair[] array, int index)
+ {
+ if (IsUndefined)
+ {
+ return;
+ }
+ EnsureDictionary().CopyTo(array, index);
+ }
+
+ public bool Remove(KeyValuePair item)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureDictionary().Remove(item);
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ EnsureDictionary().Add(key, value);
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureDictionary().ContainsKey(key);
+ }
+
+ public bool Remove(TKey key)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureDictionary().Remove(key);
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ if (IsUndefined)
+ {
+ value = default;
+ return false;
+ }
+ return EnsureDictionary().TryGetValue(key, out value);
+ }
+
+ public IDictionary EnsureDictionary()
+ {
+ return _innerDictionary ??= new Dictionary();
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingList.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingList.cs
new file mode 100644
index 0000000000..1837046c52
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ChangeTrackingList.cs
@@ -0,0 +1,153 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Azure.ResourceManager
+{
+ internal class ChangeTrackingList : IList, IReadOnlyList
+ {
+ private IList _innerList;
+
+ public ChangeTrackingList()
+ {
+ }
+
+ public ChangeTrackingList(IList innerList)
+ {
+ if (innerList != null)
+ {
+ _innerList = innerList;
+ }
+ }
+
+ public ChangeTrackingList(IReadOnlyList innerList)
+ {
+ if (innerList != null)
+ {
+ _innerList = innerList.ToList();
+ }
+ }
+
+ public bool IsUndefined => _innerList == null;
+
+ public int Count => IsUndefined ? 0 : EnsureList().Count;
+
+ public bool IsReadOnly => IsUndefined ? false : EnsureList().IsReadOnly;
+
+ public T this[int index]
+ {
+ get
+ {
+ if (IsUndefined)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ return EnsureList()[index];
+ }
+ set
+ {
+ if (IsUndefined)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ EnsureList()[index] = value;
+ }
+ }
+
+ public void Reset()
+ {
+ _innerList = null;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ if (IsUndefined)
+ {
+ IEnumerator enumerateEmpty()
+ {
+ yield break;
+ }
+ return enumerateEmpty();
+ }
+ return EnsureList().GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public void Add(T item)
+ {
+ EnsureList().Add(item);
+ }
+
+ public void Clear()
+ {
+ EnsureList().Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureList().Contains(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ if (IsUndefined)
+ {
+ return;
+ }
+ EnsureList().CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(T item)
+ {
+ if (IsUndefined)
+ {
+ return false;
+ }
+ return EnsureList().Remove(item);
+ }
+
+ public int IndexOf(T item)
+ {
+ if (IsUndefined)
+ {
+ return -1;
+ }
+ return EnsureList().IndexOf(item);
+ }
+
+ public void Insert(int index, T item)
+ {
+ EnsureList().Insert(index, item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ if (IsUndefined)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ EnsureList().RemoveAt(index);
+ }
+
+ public IList EnsureList()
+ {
+ return _innerList ??= new List();
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ModelSerializationExtensions.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ModelSerializationExtensions.cs
new file mode 100644
index 0000000000..c879f184e7
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/ModelSerializationExtensions.cs
@@ -0,0 +1,407 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Text.Json;
+using System.Xml;
+using Azure.Core;
+
+namespace Azure.ResourceManager
+{
+ internal static class ModelSerializationExtensions
+ {
+ internal static readonly JsonDocumentOptions JsonDocumentOptions = new JsonDocumentOptions { MaxDepth = 256 };
+ internal static readonly ModelReaderWriterOptions WireOptions = new ModelReaderWriterOptions("W");
+ internal static readonly BinaryData SentinelValue = BinaryData.FromBytes("\"__EMPTY__\""u8.ToArray());
+
+ public static object GetObject(this JsonElement element)
+ {
+ switch (element.ValueKind)
+ {
+ case JsonValueKind.String:
+ return element.GetString();
+ case JsonValueKind.Number:
+ if (element.TryGetInt32(out int intValue))
+ {
+ return intValue;
+ }
+ if (element.TryGetInt64(out long longValue))
+ {
+ return longValue;
+ }
+ return element.GetDouble();
+ case JsonValueKind.True:
+ return true;
+ case JsonValueKind.False:
+ return false;
+ case JsonValueKind.Undefined:
+ case JsonValueKind.Null:
+ return null;
+ case JsonValueKind.Object:
+ var dictionary = new Dictionary();
+ foreach (var jsonProperty in element.EnumerateObject())
+ {
+ dictionary.Add(jsonProperty.Name, jsonProperty.Value.GetObject());
+ }
+ return dictionary;
+ case JsonValueKind.Array:
+ var list = new List();
+ foreach (var item in element.EnumerateArray())
+ {
+ list.Add(item.GetObject());
+ }
+ return list.ToArray();
+ default:
+ throw new NotSupportedException($"Not supported value kind {element.ValueKind}");
+ }
+ }
+
+ public static byte[] GetBytesFromBase64(this JsonElement element, string format)
+ {
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+
+ return format switch
+ {
+ "U" => TypeFormatters.FromBase64UrlString(element.GetRequiredString()),
+ "D" => element.GetBytesFromBase64(),
+ _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format))
+ };
+ }
+
+ public static DateTimeOffset GetDateTimeOffset(this JsonElement element, string format) => format switch
+ {
+ "U" when element.ValueKind == JsonValueKind.Number => DateTimeOffset.FromUnixTimeSeconds(element.GetInt64()),
+ _ => TypeFormatters.ParseDateTimeOffset(element.GetString(), format)
+ };
+
+ public static TimeSpan GetTimeSpan(this JsonElement element, string format) => TypeFormatters.ParseTimeSpan(element.GetString(), format);
+
+ public static char GetChar(this JsonElement element)
+ {
+ if (element.ValueKind == JsonValueKind.String)
+ {
+ var text = element.GetString();
+ if (text == null || text.Length != 1)
+ {
+ throw new NotSupportedException($"Cannot convert \"{text}\" to a char");
+ }
+ return text[0];
+ }
+ else
+ {
+ throw new NotSupportedException($"Cannot convert {element.ValueKind} to a char");
+ }
+ }
+
+ [Conditional("DEBUG")]
+ public static void ThrowNonNullablePropertyIsNull(this JsonProperty property)
+ {
+ throw new JsonException($"A property '{property.Name}' defined as non-nullable but received as null from the service. This exception only happens in DEBUG builds of the library and would be ignored in the release build");
+ }
+
+ public static string GetRequiredString(this JsonElement element)
+ {
+ var value = element.GetString();
+ if (value == null)
+ {
+ throw new InvalidOperationException($"The requested operation requires an element of type 'String', but the target element has type '{element.ValueKind}'.");
+ }
+ return value;
+ }
+
+ public static void WriteStringValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
+ {
+ writer.WriteStringValue(TypeFormatters.ToString(value, format));
+ }
+
+ public static void WriteStringValue(this Utf8JsonWriter writer, DateTime value, string format)
+ {
+ writer.WriteStringValue(TypeFormatters.ToString(value, format));
+ }
+
+ public static void WriteStringValue(this Utf8JsonWriter writer, TimeSpan value, string format)
+ {
+ writer.WriteStringValue(TypeFormatters.ToString(value, format));
+ }
+
+ public static void WriteStringValue(this Utf8JsonWriter writer, char value)
+ {
+ writer.WriteStringValue(value.ToString(CultureInfo.InvariantCulture));
+ }
+
+ public static void WriteBase64StringValue(this Utf8JsonWriter writer, byte[] value, string format)
+ {
+ if (value == null)
+ {
+ writer.WriteNullValue();
+ return;
+ }
+ switch (format)
+ {
+ case "U":
+ writer.WriteStringValue(TypeFormatters.ToBase64UrlString(value));
+ break;
+ case "D":
+ writer.WriteBase64StringValue(value);
+ break;
+ default:
+ throw new ArgumentException($"Format is not supported: '{format}'", nameof(format));
+ }
+ }
+
+ public static void WriteNumberValue(this Utf8JsonWriter writer, DateTimeOffset value, string format)
+ {
+ if (format != "U")
+ {
+ throw new ArgumentOutOfRangeException(nameof(format), "Only 'U' format is supported when writing a DateTimeOffset as a Number.");
+ }
+ writer.WriteNumberValue(value.ToUnixTimeSeconds());
+ }
+
+ public static void WriteObjectValue(this Utf8JsonWriter writer, T value, ModelReaderWriterOptions options = null)
+ {
+ switch (value)
+ {
+ case null:
+ writer.WriteNullValue();
+ break;
+ case IJsonModel jsonModel:
+ jsonModel.Write(writer, options ?? WireOptions);
+ break;
+ case IUtf8JsonSerializable serializable:
+ serializable.Write(writer);
+ break;
+ case byte[] bytes:
+ writer.WriteBase64StringValue(bytes);
+ break;
+ case BinaryData bytes0:
+ writer.WriteBase64StringValue(bytes0);
+ break;
+ case JsonElement json:
+ json.WriteTo(writer);
+ break;
+ case int i:
+ writer.WriteNumberValue(i);
+ break;
+ case decimal d:
+ writer.WriteNumberValue(d);
+ break;
+ case double d0:
+ if (double.IsNaN(d0))
+ {
+ writer.WriteStringValue("NaN");
+ }
+ else
+ {
+ writer.WriteNumberValue(d0);
+ }
+ break;
+ case float f:
+ writer.WriteNumberValue(f);
+ break;
+ case long l:
+ writer.WriteNumberValue(l);
+ break;
+ case string s:
+ writer.WriteStringValue(s);
+ break;
+ case bool b:
+ writer.WriteBooleanValue(b);
+ break;
+ case Guid g:
+ writer.WriteStringValue(g);
+ break;
+ case DateTimeOffset dateTimeOffset:
+ writer.WriteStringValue(dateTimeOffset, "O");
+ break;
+ case DateTime dateTime:
+ writer.WriteStringValue(dateTime, "O");
+ break;
+ case IEnumerable> enumerable:
+ writer.WriteStartObject();
+ foreach (var pair in enumerable)
+ {
+ writer.WritePropertyName(pair.Key);
+ writer.WriteObjectValue(pair.Value, options);
+ }
+ writer.WriteEndObject();
+ break;
+ case IEnumerable objectEnumerable:
+ writer.WriteStartArray();
+ foreach (var item in objectEnumerable)
+ {
+ writer.WriteObjectValue(item, options);
+ }
+ writer.WriteEndArray();
+ break;
+ case TimeSpan timeSpan:
+ writer.WriteStringValue(timeSpan, "P");
+ break;
+ default:
+ throw new NotSupportedException($"Not supported type {value.GetType()}");
+ }
+ }
+
+ public static void WriteObjectValue(this Utf8JsonWriter writer, object value, ModelReaderWriterOptions options = null)
+ {
+ writer.WriteObjectValue(value, options);
+ }
+
+ internal static bool IsSentinelValue(BinaryData value)
+ {
+ ReadOnlySpan sentinelSpan = SentinelValue.ToMemory().Span;
+ ReadOnlySpan valueSpan = value.ToMemory().Span;
+ return sentinelSpan.SequenceEqual(valueSpan);
+ }
+
+ internal static class TypeFormatters
+ {
+ private const string RoundtripZFormat = "yyyy-MM-ddTHH:mm:ss.fffffffZ";
+ public const string DefaultNumberFormat = "G";
+
+ public static string ToString(bool value) => value ? "true" : "false";
+
+ public static string ToString(DateTime value, string format) => value.Kind switch
+ {
+ DateTimeKind.Utc => ToString((DateTimeOffset)value, format),
+ _ => throw new NotSupportedException($"DateTime {value} has a Kind of {value.Kind}. Azure SDK requires it to be UTC. You can call DateTime.SpecifyKind to change Kind property value to DateTimeKind.Utc.")
+ };
+
+ public static string ToString(DateTimeOffset value, string format) => format switch
+ {
+ "D" => value.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture),
+ "U" => value.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture),
+ "O" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture),
+ "o" => value.ToUniversalTime().ToString(RoundtripZFormat, CultureInfo.InvariantCulture),
+ "R" => value.ToString("r", CultureInfo.InvariantCulture),
+ _ => value.ToString(format, CultureInfo.InvariantCulture)
+ };
+
+ public static string ToString(TimeSpan value, string format) => format switch
+ {
+ "P" => XmlConvert.ToString(value),
+ _ => value.ToString(format, CultureInfo.InvariantCulture)
+ };
+
+ public static string ToString(byte[] value, string format) => format switch
+ {
+ "U" => ToBase64UrlString(value),
+ "D" => Convert.ToBase64String(value),
+ _ => throw new ArgumentException($"Format is not supported: '{format}'", nameof(format))
+ };
+
+ public static string ToBase64UrlString(byte[] value)
+ {
+ int numWholeOrPartialInputBlocks = checked(value.Length + 2) / 3;
+ int size = checked(numWholeOrPartialInputBlocks * 4);
+ char[] output = new char[size];
+
+ int numBase64Chars = Convert.ToBase64CharArray(value, 0, value.Length, output, 0);
+
+ int i = 0;
+ for (; i < numBase64Chars; i++)
+ {
+ char ch = output[i];
+ if (ch == '+')
+ {
+ output[i] = '-';
+ }
+ else
+ {
+ if (ch == '/')
+ {
+ output[i] = '_';
+ }
+ else
+ {
+ if (ch == '=')
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return new string(output, 0, i);
+ }
+
+ public static byte[] FromBase64UrlString(string value)
+ {
+ int paddingCharsToAdd = (value.Length % 4) switch
+ {
+ 0 => 0,
+ 2 => 2,
+ 3 => 1,
+ _ => throw new InvalidOperationException("Malformed input")
+ };
+ char[] output = new char[(value.Length + paddingCharsToAdd)];
+ int i = 0;
+ for (; i < value.Length; i++)
+ {
+ char ch = value[i];
+ if (ch == '-')
+ {
+ output[i] = '+';
+ }
+ else
+ {
+ if (ch == '_')
+ {
+ output[i] = '/';
+ }
+ else
+ {
+ output[i] = ch;
+ }
+ }
+ }
+
+ for (; i < output.Length; i++)
+ {
+ output[i] = '=';
+ }
+
+ return Convert.FromBase64CharArray(output, 0, output.Length);
+ }
+
+ public static DateTimeOffset ParseDateTimeOffset(string value, string format) => format switch
+ {
+ "U" => DateTimeOffset.FromUnixTimeSeconds(long.Parse(value, CultureInfo.InvariantCulture)),
+ _ => DateTimeOffset.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal)
+ };
+
+ public static TimeSpan ParseTimeSpan(string value, string format) => format switch
+ {
+ "P" => XmlConvert.ToTimeSpan(value),
+ _ => TimeSpan.ParseExact(value, format, CultureInfo.InvariantCulture)
+ };
+
+ public static string ConvertToString(object value, string format = null) => value switch
+ {
+ null => "null",
+ string s => s,
+ bool b => ToString(b),
+ int or float or double or long or decimal => ((IFormattable)value).ToString(DefaultNumberFormat, CultureInfo.InvariantCulture),
+ byte[] b0 when format != null => ToString(b0, format),
+ IEnumerable s0 => string.Join(",", s0),
+ DateTimeOffset dateTime when format != null => ToString(dateTime, format),
+ TimeSpan timeSpan when format != null => ToString(timeSpan, format),
+ TimeSpan timeSpan0 => XmlConvert.ToString(timeSpan0),
+ Guid guid => guid.ToString(),
+ BinaryData binaryData => ConvertToString(binaryData.ToArray(), format),
+ _ => value.ToString()
+ };
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Optional.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Optional.cs
new file mode 100644
index 0000000000..c21cb37eee
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/Optional.cs
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace Azure.ResourceManager
+{
+ internal static class Optional
+ {
+ public static bool IsCollectionDefined(IEnumerable collection)
+ {
+ return !(collection is ChangeTrackingList changeTrackingList && changeTrackingList.IsUndefined);
+ }
+
+ public static bool IsCollectionDefined(IDictionary collection)
+ {
+ return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined);
+ }
+
+ public static bool IsCollectionDefined(IReadOnlyDictionary collection)
+ {
+ return !(collection is ChangeTrackingDictionary changeTrackingDictionary && changeTrackingDictionary.IsUndefined);
+ }
+
+ public static bool IsDefined(T? value)
+ where T : struct
+ {
+ return value.HasValue;
+ }
+
+ public static bool IsDefined(object value)
+ {
+ return value != null;
+ }
+
+ public static bool IsDefined(JsonElement value)
+ {
+ return value.ValueKind != JsonValueKind.Undefined;
+ }
+
+ public static bool IsDefined(string value)
+ {
+ return value != null;
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/WirePathAttribute.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/WirePathAttribute.cs
new file mode 100644
index 0000000000..6a974d2a89
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Internal/WirePathAttribute.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+
+namespace Azure.ResourceManager
+{
+ [AttributeUsage(AttributeTargets.Property)]
+ internal class WirePathAttribute : Attribute
+ {
+ private string _wirePath;
+
+ public WirePathAttribute(string wirePath)
+ {
+ _wirePath = wirePath;
+ }
+
+ public override string ToString()
+ {
+ return _wirePath;
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.Serialization.cs
new file mode 100644
index 0000000000..95e2fd6d05
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.Serialization.cs
@@ -0,0 +1,291 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(ArmPlanConverter))]
+ public partial class ArmPlan : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ private void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ArmPlan)} does not support writing '{format}' format.");
+ }
+
+ writer.WritePropertyName("name"u8);
+ writer.WriteStringValue(Name);
+ writer.WritePropertyName("publisher"u8);
+ writer.WriteStringValue(Publisher);
+ writer.WritePropertyName("product"u8);
+ writer.WriteStringValue(Product);
+ if (Optional.IsDefined(PromotionCode))
+ {
+ writer.WritePropertyName("promotionCode"u8);
+ writer.WriteStringValue(PromotionCode);
+ }
+ if (Optional.IsDefined(Version))
+ {
+ writer.WritePropertyName("version"u8);
+ writer.WriteStringValue(Version);
+ }
+ }
+
+ ArmPlan IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ArmPlan)} does not support reading '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeArmPlan(document.RootElement, options);
+ }
+
+ internal static ArmPlan DeserializeArmPlan(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ options ??= ModelSerializationExtensions.WireOptions;
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string name = default;
+ string publisher = default;
+ string product = default;
+ string promotionCode = default;
+ string version = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("name"u8))
+ {
+ name = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("publisher"u8))
+ {
+ publisher = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("product"u8))
+ {
+ product = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("promotionCode"u8))
+ {
+ promotionCode = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("version"u8))
+ {
+ version = property.Value.GetString();
+ continue;
+ }
+ }
+ return new ArmPlan(name, publisher, product, promotionCode, version);
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Name), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" name: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Name))
+ {
+ builder.Append(" name: ");
+ if (Name.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Name}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Name}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Publisher), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" publisher: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Publisher))
+ {
+ builder.Append(" publisher: ");
+ if (Publisher.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Publisher}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Publisher}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Product), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" product: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Product))
+ {
+ builder.Append(" product: ");
+ if (Product.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Product}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Product}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(PromotionCode), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" promotionCode: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(PromotionCode))
+ {
+ builder.Append(" promotionCode: ");
+ if (PromotionCode.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{PromotionCode}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{PromotionCode}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Version), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" version: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Version))
+ {
+ builder.Append(" version: ");
+ if (Version.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Version}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Version}'");
+ }
+ }
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(ArmPlan)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ ArmPlan IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeArmPlan(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ArmPlan)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class ArmPlanConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, ArmPlan model, JsonSerializerOptions options)
+ {
+ writer.WriteObjectValue(model, ModelSerializationExtensions.WireOptions);
+ }
+
+ public override ArmPlan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeArmPlan(document.RootElement);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.cs
new file mode 100644
index 0000000000..711ac5f348
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmPlan.cs
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Plan for the resource.
+ [PropertyReferenceType]
+ public partial class ArmPlan
+ {
+ /// Initializes a new instance of .
+ /// A user defined name of the 3rd Party Artifact that is being procured.
+ /// The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic.
+ /// The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding.
+ /// , or is null.
+ [InitializationConstructor]
+ public ArmPlan(string name, string publisher, string product)
+ {
+ Argument.AssertNotNull(name, nameof(name));
+ Argument.AssertNotNull(publisher, nameof(publisher));
+ Argument.AssertNotNull(product, nameof(product));
+
+ Name = name;
+ Publisher = publisher;
+ Product = product;
+ }
+
+ /// Initializes a new instance of .
+ /// A user defined name of the 3rd Party Artifact that is being procured.
+ /// The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic.
+ /// The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding.
+ /// A publisher provided promotion code as provisioned in Data Market for the said product/artifact.
+ /// The version of the desired product/artifact.
+ [SerializationConstructor]
+ internal ArmPlan(string name, string publisher, string product, string promotionCode, string version)
+ {
+ Name = name;
+ Publisher = publisher;
+ Product = product;
+ PromotionCode = promotionCode;
+ Version = version;
+ }
+
+ /// Initializes a new instance of for deserialization.
+ internal ArmPlan()
+ {
+ }
+
+ /// A user defined name of the 3rd Party Artifact that is being procured.
+ [WirePath("name")]
+ public string Name { get; set; }
+ /// The publisher of the 3rd Party Artifact that is being bought. E.g. NewRelic.
+ [WirePath("publisher")]
+ public string Publisher { get; set; }
+ /// The 3rd Party artifact that is being procured. E.g. NewRelic. Product maps to the OfferID specified for the artifact at the time of Data Market onboarding.
+ [WirePath("product")]
+ public string Product { get; set; }
+ /// A publisher provided promotion code as provisioned in Data Market for the said product/artifact.
+ [WirePath("promotionCode")]
+ public string PromotionCode { get; set; }
+ /// The version of the desired product/artifact.
+ [WirePath("version")]
+ public string Version { get; set; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.Serialization.cs
new file mode 100644
index 0000000000..ee12d1ffab
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.Serialization.cs
@@ -0,0 +1,289 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(ArmSkuConverter))]
+ public partial class ArmSku : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ private void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ArmSku)} does not support writing '{format}' format.");
+ }
+
+ writer.WritePropertyName("name"u8);
+ writer.WriteStringValue(Name);
+ if (Optional.IsDefined(Tier))
+ {
+ writer.WritePropertyName("tier"u8);
+ writer.WriteStringValue(Tier.Value.ToSerialString());
+ }
+ if (Optional.IsDefined(Size))
+ {
+ writer.WritePropertyName("size"u8);
+ writer.WriteStringValue(Size);
+ }
+ if (Optional.IsDefined(Family))
+ {
+ writer.WritePropertyName("family"u8);
+ writer.WriteStringValue(Family);
+ }
+ if (Optional.IsDefined(Capacity))
+ {
+ writer.WritePropertyName("capacity"u8);
+ writer.WriteNumberValue(Capacity.Value);
+ }
+ }
+
+ ArmSku IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(ArmSku)} does not support reading '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeArmSku(document.RootElement, options);
+ }
+
+ internal static ArmSku DeserializeArmSku(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ options ??= ModelSerializationExtensions.WireOptions;
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string name = default;
+ ArmSkuTier? tier = default;
+ string size = default;
+ string family = default;
+ int? capacity = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("name"u8))
+ {
+ name = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("tier"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ tier = property.Value.GetString().ToArmSkuTier();
+ continue;
+ }
+ if (property.NameEquals("size"u8))
+ {
+ size = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("family"u8))
+ {
+ family = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("capacity"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ capacity = property.Value.GetInt32();
+ continue;
+ }
+ }
+ return new ArmSku(name, tier, size, family, capacity);
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Name), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" name: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Name))
+ {
+ builder.Append(" name: ");
+ if (Name.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Name}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Name}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Tier), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" tier: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Tier))
+ {
+ builder.Append(" tier: ");
+ builder.AppendLine($"'{Tier.Value.ToSerialString()}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Size), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" size: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Size))
+ {
+ builder.Append(" size: ");
+ if (Size.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Size}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Size}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Family), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" family: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Family))
+ {
+ builder.Append(" family: ");
+ if (Family.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Family}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Family}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Capacity), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" capacity: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Capacity))
+ {
+ builder.Append(" capacity: ");
+ builder.AppendLine($"{Capacity.Value}");
+ }
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(ArmSku)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ ArmSku IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeArmSku(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ArmSku)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class ArmSkuConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, ArmSku model, JsonSerializerOptions options)
+ {
+ writer.WriteObjectValue(model, ModelSerializationExtensions.WireOptions);
+ }
+
+ public override ArmSku Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeArmSku(document.RootElement);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.cs
new file mode 100644
index 0000000000..4a4de3ba03
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSku.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// The resource model definition representing SKU.
+ [PropertyReferenceType]
+ public partial class ArmSku
+ {
+ /// Initializes a new instance of .
+ /// The name of the SKU. Ex - P3. It is typically a letter+number code.
+ /// is null.
+ [InitializationConstructor]
+ public ArmSku(string name)
+ {
+ Argument.AssertNotNull(name, nameof(name));
+
+ Name = name;
+ }
+
+ /// Initializes a new instance of .
+ /// The name of the SKU. Ex - P3. It is typically a letter+number code.
+ /// This field is required to be implemented by the Resource Provider if the service has more than one tier, but is not required on a PUT.
+ /// The SKU size. When the name field is the combination of tier and some other value, this would be the standalone code.
+ /// If the service has different generations of hardware, for the same SKU, then that can be captured here.
+ /// If the SKU supports scale out/in then the capacity integer should be included. If scale out/in is not possible for the resource this may be omitted.
+ [SerializationConstructor]
+ internal ArmSku(string name, ArmSkuTier? tier, string size, string family, int? capacity)
+ {
+ Name = name;
+ Tier = tier;
+ Size = size;
+ Family = family;
+ Capacity = capacity;
+ }
+
+ /// Initializes a new instance of for deserialization.
+ internal ArmSku()
+ {
+ }
+
+ /// The name of the SKU. Ex - P3. It is typically a letter+number code.
+ [WirePath("name")]
+ public string Name { get; set; }
+ /// This field is required to be implemented by the Resource Provider if the service has more than one tier, but is not required on a PUT.
+ [WirePath("tier")]
+ public ArmSkuTier? Tier { get; set; }
+ /// The SKU size. When the name field is the combination of tier and some other value, this would be the standalone code.
+ [WirePath("size")]
+ public string Size { get; set; }
+ /// If the service has different generations of hardware, for the same SKU, then that can be captured here.
+ [WirePath("family")]
+ public string Family { get; set; }
+ /// If the SKU supports scale out/in then the capacity integer should be included. If scale out/in is not possible for the resource this may be omitted.
+ [WirePath("capacity")]
+ public int? Capacity { get; set; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.Serialization.cs
new file mode 100644
index 0000000000..c640e16a48
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.Serialization.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+
+namespace Azure.ResourceManager.Models
+{
+ internal static partial class ArmSkuTierExtensions
+ {
+ public static string ToSerialString(this ArmSkuTier value) => value switch
+ {
+ ArmSkuTier.Free => "Free",
+ ArmSkuTier.Basic => "Basic",
+ ArmSkuTier.Standard => "Standard",
+ ArmSkuTier.Premium => "Premium",
+ _ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ArmSkuTier value.")
+ };
+
+ public static ArmSkuTier ToArmSkuTier(this string value)
+ {
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, "Free")) return ArmSkuTier.Free;
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, "Basic")) return ArmSkuTier.Basic;
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, "Standard")) return ArmSkuTier.Standard;
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, "Premium")) return ArmSkuTier.Premium;
+ throw new ArgumentOutOfRangeException(nameof(value), value, "Unknown ArmSkuTier value.");
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.cs
new file mode 100644
index 0000000000..4320a2d3b4
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ArmSkuTier.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+namespace Azure.ResourceManager.Models
+{
+ /// This field is required to be implemented by the Resource Provider if the service has more than one tier, but is not required on a PUT.
+ public enum ArmSkuTier
+ {
+ /// Free.
+ Free,
+ /// Basic.
+ Basic,
+ /// Standard.
+ Standard,
+ /// Premium.
+ Premium
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/AzureResourceManagerContext.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/AzureResourceManagerContext.cs
new file mode 100644
index 0000000000..f26fee2f3a
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/AzureResourceManagerContext.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System.ClientModel.Primitives;
+
+namespace Azure.ResourceManager
+{
+ ///
+ /// Context class which will be filled in by the System.ClientModel.SourceGeneration.
+ /// For more information see 'https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/System.ClientModel/src/docs/ModelReaderWriterContext.md'
+ ///
+ public partial class AzureResourceManagerContext : ModelReaderWriterContext
+ {
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/CreatedByType.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/CreatedByType.cs
new file mode 100644
index 0000000000..f7a4c34f58
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/CreatedByType.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ /// The type of identity that created the resource.
+ public readonly partial struct CreatedByType : IEquatable
+ {
+ private readonly string _value;
+
+ /// Initializes a new instance of .
+ /// is null.
+ public CreatedByType(string value)
+ {
+ _value = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ private const string UserValue = "User";
+ private const string ApplicationValue = "Application";
+ private const string ManagedIdentityValue = "ManagedIdentity";
+ private const string KeyValue = "Key";
+
+ /// User.
+ public static CreatedByType User { get; } = new CreatedByType(UserValue);
+ /// Application.
+ public static CreatedByType Application { get; } = new CreatedByType(ApplicationValue);
+ /// ManagedIdentity.
+ public static CreatedByType ManagedIdentity { get; } = new CreatedByType(ManagedIdentityValue);
+ /// Key.
+ public static CreatedByType Key { get; } = new CreatedByType(KeyValue);
+ /// Determines if two values are the same.
+ public static bool operator ==(CreatedByType left, CreatedByType right) => left.Equals(right);
+ /// Determines if two values are not the same.
+ public static bool operator !=(CreatedByType left, CreatedByType right) => !left.Equals(right);
+ /// Converts a to a .
+ public static implicit operator CreatedByType(string value) => new CreatedByType(value);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj) => obj is CreatedByType other && Equals(other);
+ ///
+ public bool Equals(CreatedByType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
+ ///
+ public override string ToString() => _value;
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.Serialization.cs
new file mode 100644
index 0000000000..bc9ff0979a
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.Serialization.cs
@@ -0,0 +1,190 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(EncryptionPropertiesConverter))]
+ public partial class EncryptionProperties : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(EncryptionProperties)} does not support writing '{format}' format.");
+ }
+
+ if (Optional.IsDefined(Status))
+ {
+ writer.WritePropertyName("status"u8);
+ writer.WriteStringValue(Status.Value.ToString());
+ }
+ if (Optional.IsDefined(KeyVaultProperties))
+ {
+ writer.WritePropertyName("keyVaultProperties"u8);
+ writer.WriteObjectValue(KeyVaultProperties, options);
+ }
+ }
+
+ EncryptionProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(EncryptionProperties)} does not support reading '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeEncryptionProperties(document.RootElement, options);
+ }
+
+ internal static EncryptionProperties DeserializeEncryptionProperties(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ options ??= ModelSerializationExtensions.WireOptions;
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ EncryptionStatus? status = default;
+ KeyVaultProperties keyVaultProperties = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("status"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ status = new EncryptionStatus(property.Value.GetString());
+ continue;
+ }
+ if (property.NameEquals("keyVaultProperties"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ keyVaultProperties = KeyVaultProperties.DeserializeKeyVaultProperties(property.Value, options);
+ continue;
+ }
+ }
+ return new EncryptionProperties(status, keyVaultProperties);
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Status), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" status: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Status))
+ {
+ builder.Append(" status: ");
+ builder.AppendLine($"'{Status.Value.ToString()}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(KeyVaultProperties), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" keyVaultProperties: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(KeyVaultProperties))
+ {
+ builder.Append(" keyVaultProperties: ");
+ BicepSerializationHelpers.AppendChildObject(builder, KeyVaultProperties, options, 2, false, " keyVaultProperties: ");
+ }
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(EncryptionProperties)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ EncryptionProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeEncryptionProperties(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(EncryptionProperties)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class EncryptionPropertiesConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, EncryptionProperties model, JsonSerializerOptions options)
+ {
+ writer.WriteObjectValue(model, ModelSerializationExtensions.WireOptions);
+ }
+
+ public override EncryptionProperties Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeEncryptionProperties(document.RootElement);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.cs
new file mode 100644
index 0000000000..5b441bcc81
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionProperties.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Configuration of key for data encryption.
+ [PropertyReferenceType]
+ public partial class EncryptionProperties
+ {
+ /// Initializes a new instance of .
+ [InitializationConstructor]
+ public EncryptionProperties()
+ {
+ }
+
+ /// Initializes a new instance of .
+ /// Indicates whether or not the encryption is enabled for container registry.
+ /// Key vault properties.
+ [SerializationConstructor]
+ internal EncryptionProperties(EncryptionStatus? status, KeyVaultProperties keyVaultProperties)
+ {
+ Status = status;
+ KeyVaultProperties = keyVaultProperties;
+ }
+
+ /// Indicates whether or not the encryption is enabled for container registry.
+ [WirePath("status")]
+ public EncryptionStatus? Status { get; set; }
+ /// Key vault properties.
+ [WirePath("keyVaultProperties")]
+ public KeyVaultProperties KeyVaultProperties { get; set; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionStatus.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionStatus.cs
new file mode 100644
index 0000000000..c69242b97c
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/EncryptionStatus.cs
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Indicates whether or not the encryption is enabled for container registry.
+ public readonly partial struct EncryptionStatus : IEquatable
+ {
+ private readonly string _value;
+
+ /// Initializes a new instance of .
+ /// is null.
+ public EncryptionStatus(string value)
+ {
+ _value = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ private const string EnabledValue = "enabled";
+ private const string DisabledValue = "disabled";
+
+ /// enabled.
+ public static EncryptionStatus Enabled { get; } = new EncryptionStatus(EnabledValue);
+ /// disabled.
+ public static EncryptionStatus Disabled { get; } = new EncryptionStatus(DisabledValue);
+ /// Determines if two values are the same.
+ public static bool operator ==(EncryptionStatus left, EncryptionStatus right) => left.Equals(right);
+ /// Determines if two values are not the same.
+ public static bool operator !=(EncryptionStatus left, EncryptionStatus right) => !left.Equals(right);
+ /// Converts a to a .
+ public static implicit operator EncryptionStatus(string value) => new EncryptionStatus(value);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj) => obj is EncryptionStatus other && Equals(other);
+ ///
+ public bool Equals(EncryptionStatus other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
+ ///
+ public override string ToString() => _value;
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.Serialization.cs
new file mode 100644
index 0000000000..5280cd7b90
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.Serialization.cs
@@ -0,0 +1,198 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(KeyVaultPropertiesConverter))]
+ public partial class KeyVaultProperties : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(KeyVaultProperties)} does not support writing '{format}' format.");
+ }
+
+ if (Optional.IsDefined(KeyIdentifier))
+ {
+ writer.WritePropertyName("keyIdentifier"u8);
+ writer.WriteStringValue(KeyIdentifier);
+ }
+ if (Optional.IsDefined(Identity))
+ {
+ writer.WritePropertyName("identity"u8);
+ writer.WriteStringValue(Identity);
+ }
+ }
+
+ KeyVaultProperties IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(KeyVaultProperties)} does not support reading '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeKeyVaultProperties(document.RootElement, options);
+ }
+
+ internal static KeyVaultProperties DeserializeKeyVaultProperties(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ options ??= ModelSerializationExtensions.WireOptions;
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string keyIdentifier = default;
+ string identity = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("keyIdentifier"u8))
+ {
+ keyIdentifier = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("identity"u8))
+ {
+ identity = property.Value.GetString();
+ continue;
+ }
+ }
+ return new KeyVaultProperties(keyIdentifier, identity);
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(KeyIdentifier), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" keyIdentifier: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(KeyIdentifier))
+ {
+ builder.Append(" keyIdentifier: ");
+ if (KeyIdentifier.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{KeyIdentifier}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{KeyIdentifier}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Identity), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" identity: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Identity))
+ {
+ builder.Append(" identity: ");
+ if (Identity.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Identity}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Identity}'");
+ }
+ }
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(KeyVaultProperties)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ KeyVaultProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeKeyVaultProperties(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(KeyVaultProperties)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class KeyVaultPropertiesConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, KeyVaultProperties model, JsonSerializerOptions options)
+ {
+ writer.WriteObjectValue(model, ModelSerializationExtensions.WireOptions);
+ }
+
+ public override KeyVaultProperties Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeKeyVaultProperties(document.RootElement);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.cs
new file mode 100644
index 0000000000..2e92a30cff
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/KeyVaultProperties.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// The KeyVaultProperties.
+ [PropertyReferenceType]
+ public partial class KeyVaultProperties
+ {
+ /// Initializes a new instance of .
+ [InitializationConstructor]
+ public KeyVaultProperties()
+ {
+ }
+
+ /// Initializes a new instance of .
+ /// Key vault uri to access the encryption key.
+ /// The client ID of the identity which will be used to access key vault.
+ [SerializationConstructor]
+ internal KeyVaultProperties(string keyIdentifier, string identity)
+ {
+ KeyIdentifier = keyIdentifier;
+ Identity = identity;
+ }
+
+ /// Key vault uri to access the encryption key.
+ [WirePath("keyIdentifier")]
+ public string KeyIdentifier { get; set; }
+ /// The client ID of the identity which will be used to access key vault.
+ [WirePath("identity")]
+ public string Identity { get; set; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ManagedServiceIdentityType.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ManagedServiceIdentityType.cs
new file mode 100644
index 0000000000..826953ce1c
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ManagedServiceIdentityType.cs
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ComponentModel;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Type of managed service identity (where both SystemAssigned and UserAssigned types are allowed).
+ public readonly partial struct ManagedServiceIdentityType : IEquatable
+ {
+ private readonly string _value;
+
+ /// Initializes a new instance of .
+ /// is null.
+ public ManagedServiceIdentityType(string value)
+ {
+ _value = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ private const string NoneValue = "None";
+ private const string SystemAssignedValue = "SystemAssigned";
+ private const string UserAssignedValue = "UserAssigned";
+ private const string SystemAssignedUserAssignedValue = "SystemAssigned, UserAssigned";
+
+ /// None.
+ public static ManagedServiceIdentityType None { get; } = new ManagedServiceIdentityType(NoneValue);
+ /// SystemAssigned.
+ public static ManagedServiceIdentityType SystemAssigned { get; } = new ManagedServiceIdentityType(SystemAssignedValue);
+ /// UserAssigned.
+ public static ManagedServiceIdentityType UserAssigned { get; } = new ManagedServiceIdentityType(UserAssignedValue);
+ /// SystemAssigned, UserAssigned.
+ public static ManagedServiceIdentityType SystemAssignedUserAssigned { get; } = new ManagedServiceIdentityType(SystemAssignedUserAssignedValue);
+ /// Determines if two values are the same.
+ public static bool operator ==(ManagedServiceIdentityType left, ManagedServiceIdentityType right) => left.Equals(right);
+ /// Determines if two values are not the same.
+ public static bool operator !=(ManagedServiceIdentityType left, ManagedServiceIdentityType right) => !left.Equals(right);
+ /// Converts a to a .
+ public static implicit operator ManagedServiceIdentityType(string value) => new ManagedServiceIdentityType(value);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool Equals(object obj) => obj is ManagedServiceIdentityType other && Equals(other);
+ ///
+ public bool Equals(ManagedServiceIdentityType other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);
+
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override int GetHashCode() => _value != null ? StringComparer.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;
+ ///
+ public override string ToString() => _value;
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.Serialization.cs
new file mode 100644
index 0000000000..8afe4c80f4
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.Serialization.cs
@@ -0,0 +1,407 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(OperationStatusResultConverter))]
+ public partial class OperationStatusResult : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(OperationStatusResult)} does not support writing '{format}' format.");
+ }
+
+ if (options.Format != "W" && Optional.IsDefined(Id))
+ {
+ writer.WritePropertyName("id"u8);
+ writer.WriteStringValue(Id);
+ }
+ if (options.Format != "W" && Optional.IsDefined(Name))
+ {
+ writer.WritePropertyName("name"u8);
+ writer.WriteStringValue(Name);
+ }
+ if (options.Format != "W")
+ {
+ writer.WritePropertyName("status"u8);
+ writer.WriteStringValue(Status);
+ }
+ if (options.Format != "W" && Optional.IsDefined(PercentComplete))
+ {
+ writer.WritePropertyName("percentComplete"u8);
+ writer.WriteNumberValue(PercentComplete.Value);
+ }
+ if (options.Format != "W" && Optional.IsDefined(StartOn))
+ {
+ writer.WritePropertyName("startTime"u8);
+ writer.WriteStringValue(StartOn.Value, "O");
+ }
+ if (options.Format != "W" && Optional.IsDefined(EndOn))
+ {
+ writer.WritePropertyName("endTime"u8);
+ writer.WriteStringValue(EndOn.Value, "O");
+ }
+ if (options.Format != "W" && Optional.IsCollectionDefined(Operations))
+ {
+ writer.WritePropertyName("operations"u8);
+ writer.WriteStartArray();
+ foreach (var item in Operations)
+ {
+ writer.WriteObjectValue(item, options);
+ }
+ writer.WriteEndArray();
+ }
+ if (options.Format != "W" && Optional.IsDefined(Error))
+ {
+ writer.WritePropertyName("error"u8);
+ JsonSerializer.Serialize(writer, Error, ResourceManagerJsonContext.Default.ResponseError);
+ }
+ }
+
+ OperationStatusResult IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(OperationStatusResult)} does not support reading '{format}' format.");
+ }
+
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeOperationStatusResult(document.RootElement, options);
+ }
+
+ internal static OperationStatusResult DeserializeOperationStatusResult(JsonElement element, ModelReaderWriterOptions options = null)
+ {
+ options ??= ModelSerializationExtensions.WireOptions;
+
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ ResourceIdentifier id = default;
+ string name = default;
+ string status = default;
+ float? percentComplete = default;
+ DateTimeOffset? startTime = default;
+ DateTimeOffset? endTime = default;
+ IReadOnlyList operations = default;
+ ResponseError error = default;
+ foreach (var property in element.EnumerateObject())
+ {
+ if (property.NameEquals("id"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ id = new ResourceIdentifier(property.Value.GetString());
+ continue;
+ }
+ if (property.NameEquals("name"u8))
+ {
+ name = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("status"u8))
+ {
+ status = property.Value.GetString();
+ continue;
+ }
+ if (property.NameEquals("percentComplete"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ percentComplete = property.Value.GetSingle();
+ continue;
+ }
+ if (property.NameEquals("startTime"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ startTime = property.Value.GetDateTimeOffset("O");
+ continue;
+ }
+ if (property.NameEquals("endTime"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ endTime = property.Value.GetDateTimeOffset("O");
+ continue;
+ }
+ if (property.NameEquals("operations"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ List array = new List();
+ foreach (var item in property.Value.EnumerateArray())
+ {
+ array.Add(JsonSerializer.Deserialize(item.GetRawText(), ResourceManagerJsonContext.Default.OperationStatusResult));
+ }
+ operations = array;
+ continue;
+ }
+ if (property.NameEquals("error"u8))
+ {
+ if (property.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ error = JsonSerializer.Deserialize(property.Value.GetRawText(), ResourceManagerJsonContext.Default.ResponseError);
+ continue;
+ }
+ }
+ return new OperationStatusResult(
+ id,
+ name,
+ status,
+ percentComplete,
+ startTime,
+ endTime,
+ operations ?? new ChangeTrackingList(),
+ error);
+ }
+
+ private BinaryData SerializeBicep(ModelReaderWriterOptions options)
+ {
+ StringBuilder builder = new StringBuilder();
+ BicepModelReaderWriterOptions bicepOptions = options as BicepModelReaderWriterOptions;
+ IDictionary propertyOverrides = null;
+ bool hasObjectOverride = bicepOptions != null && bicepOptions.PropertyOverrides.TryGetValue(this, out propertyOverrides);
+ bool hasPropertyOverride = false;
+ string propertyOverride = null;
+
+ builder.AppendLine("{");
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Id), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" id: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Id))
+ {
+ builder.Append(" id: ");
+ builder.AppendLine($"'{Id.ToString()}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Name), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" name: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Name))
+ {
+ builder.Append(" name: ");
+ if (Name.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Name}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Name}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Status), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" status: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Status))
+ {
+ builder.Append(" status: ");
+ if (Status.Contains(Environment.NewLine))
+ {
+ builder.AppendLine("'''");
+ builder.AppendLine($"{Status}'''");
+ }
+ else
+ {
+ builder.AppendLine($"'{Status}'");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(PercentComplete), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" percentComplete: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(PercentComplete))
+ {
+ builder.Append(" percentComplete: ");
+ builder.AppendLine($"'{PercentComplete.Value.ToString()}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(StartOn), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" startTime: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(StartOn))
+ {
+ builder.Append(" startTime: ");
+ var formattedDateTimeString = TypeFormatters.ToString(StartOn.Value, "o");
+ builder.AppendLine($"'{formattedDateTimeString}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(EndOn), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" endTime: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(EndOn))
+ {
+ builder.Append(" endTime: ");
+ var formattedDateTimeString = TypeFormatters.ToString(EndOn.Value, "o");
+ builder.AppendLine($"'{formattedDateTimeString}'");
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Operations), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" operations: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsCollectionDefined(Operations))
+ {
+ if (Operations.Any())
+ {
+ builder.Append(" operations: ");
+ builder.AppendLine("[");
+ foreach (var item in Operations)
+ {
+ BicepSerializationHelpers.AppendChildObject(builder, item, options, 4, true, " operations: ");
+ }
+ builder.AppendLine(" ]");
+ }
+ }
+ }
+
+ hasPropertyOverride = hasObjectOverride && propertyOverrides.TryGetValue(nameof(Error), out propertyOverride);
+ if (hasPropertyOverride)
+ {
+ builder.Append(" error: ");
+ builder.AppendLine(propertyOverride);
+ }
+ else
+ {
+ if (Optional.IsDefined(Error))
+ {
+ builder.Append(" error: ");
+ BicepSerializationHelpers.AppendChildObject(builder, Error, options, 2, false, " error: ");
+ }
+ }
+
+ builder.AppendLine("}");
+ return BinaryData.FromString(builder.ToString());
+ }
+
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, AzureResourceManagerContext.Default);
+ case "bicep":
+ return SerializeBicep(options);
+ default:
+ throw new FormatException($"The model {nameof(OperationStatusResult)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ OperationStatusResult IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+
+ switch (format)
+ {
+ case "J":
+ {
+ using JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeOperationStatusResult(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(OperationStatusResult)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ internal partial class OperationStatusResultConverter : JsonConverter
+ {
+ public override void Write(Utf8JsonWriter writer, OperationStatusResult model, JsonSerializerOptions options)
+ {
+ writer.WriteObjectValue(model, ModelSerializationExtensions.WireOptions);
+ }
+
+ public override OperationStatusResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ using var document = JsonDocument.ParseValue(ref reader);
+ return DeserializeOperationStatusResult(document.RootElement);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.cs
new file mode 100644
index 0000000000..5a902c73e8
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/OperationStatusResult.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// The current status of an async operation.
+ [TypeReferenceType]
+ public partial class OperationStatusResult
+ {
+ /// Initializes a new instance of .
+ /// Operation status.
+ [InitializationConstructor]
+ public OperationStatusResult(string status)
+ {
+ Status = status;
+ Operations = new ChangeTrackingList();
+ }
+
+ /// Initializes a new instance of .
+ /// Fully qualified ID for the async operation.
+ /// Name of the async operation.
+ /// Operation status.
+ /// Percent of the operation that is complete.
+ /// The start time of the operation.
+ /// The end time of the operation.
+ /// The operations list.
+ /// If present, details of the operation error.
+ [SerializationConstructor]
+ protected OperationStatusResult(ResourceIdentifier id, string name, string status, float? percentComplete, DateTimeOffset? startOn, DateTimeOffset? endOn, IReadOnlyList operations, ResponseError error)
+ {
+ Id = id;
+ Name = name;
+ Status = status;
+ PercentComplete = percentComplete;
+ StartOn = startOn;
+ EndOn = endOn;
+ Operations = operations;
+ Error = error;
+ }
+
+ /// Initializes a new instance of for deserialization.
+ protected OperationStatusResult()
+ {
+ }
+
+ /// Fully qualified ID for the async operation.
+ [WirePath("id")]
+ public ResourceIdentifier Id { get; }
+ /// Name of the async operation.
+ [WirePath("name")]
+ public string Name { get; }
+ /// Operation status.
+ [WirePath("status")]
+ public string Status { get; }
+ /// Percent of the operation that is complete.
+ [WirePath("percentComplete")]
+ public float? PercentComplete { get; }
+ /// The start time of the operation.
+ [WirePath("startTime")]
+ public DateTimeOffset? StartOn { get; }
+ /// The end time of the operation.
+ [WirePath("endTime")]
+ public DateTimeOffset? EndOn { get; }
+ /// The operations list.
+ [WirePath("operations")]
+ public IReadOnlyList Operations { get; }
+ /// If present, details of the operation error.
+ [WirePath("error")]
+ public ResponseError Error { get; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.Serialization.cs
new file mode 100644
index 0000000000..1b659410bc
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.Serialization.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System.ClientModel.Primitives;
+using System.Text.Json;
+
+namespace Azure.ResourceManager.Models
+{
+ public partial class ResourceData
+ {
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ if (options.Format != "W" && Optional.IsDefined(Id))
+ {
+ writer.WritePropertyName("id"u8);
+ writer.WriteStringValue(Id);
+ }
+ if (options.Format != "W" && Optional.IsDefined(Name))
+ {
+ writer.WritePropertyName("name"u8);
+ writer.WriteStringValue(Name);
+ }
+ if (options.Format != "W")
+ {
+ writer.WritePropertyName("type"u8);
+ writer.WriteStringValue(ResourceType);
+ }
+ if (options.Format != "W" && Optional.IsDefined(SystemData))
+ {
+ writer.WritePropertyName("systemData"u8);
+ writer.WriteObjectValue(SystemData, options);
+ }
+ }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.cs
new file mode 100644
index 0000000000..841b931f44
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/ResourceData.cs
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ /// Common fields that are returned in the response for all Azure Resource Manager resources.
+ [ReferenceType(new string[] { "SystemData" })]
+ public abstract partial class ResourceData
+ {
+ /// Initializes a new instance of .
+ [InitializationConstructor]
+ protected ResourceData()
+ {
+ }
+
+ /// Initializes a new instance of .
+ /// Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
+ /// The name of the resource.
+ /// The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts".
+ /// Azure Resource Manager metadata containing createdBy and modifiedBy information.
+ [SerializationConstructor]
+ protected ResourceData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData)
+ {
+ Id = id;
+ Name = name;
+ ResourceType = resourceType;
+ SystemData = systemData;
+ }
+
+ /// Fully qualified resource ID for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}.
+ public ResourceIdentifier Id { get; }
+ /// The name of the resource.
+ public string Name { get; }
+ /// The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts".
+ public ResourceType ResourceType { get; }
+ /// Azure Resource Manager metadata containing createdBy and modifiedBy information.
+ public SystemData SystemData { get; }
+ }
+}
diff --git a/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/SystemAssignedServiceIdentity.Serialization.cs b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/SystemAssignedServiceIdentity.Serialization.cs
new file mode 100644
index 0000000000..2e420c90b8
--- /dev/null
+++ b/tests/dotnet/dotnet-aot-compat/after/Common/Generated/Models/SystemAssignedServiceIdentity.Serialization.cs
@@ -0,0 +1,210 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Azure.Core;
+
+namespace Azure.ResourceManager.Models
+{
+ [JsonConverter(typeof(SystemAssignedServiceIdentityConverter))]
+ public partial class SystemAssignedServiceIdentity : IUtf8JsonSerializable, IJsonModel
+ {
+ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer) => ((IJsonModel)this).Write(writer, ModelSerializationExtensions.WireOptions);
+
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(SystemAssignedServiceIdentity)} does not support writing '{format}' format.");
+ }
+
+ if (options.Format != "W" && Optional.IsDefined(PrincipalId))
+ {
+ writer.WritePropertyName("principalId"u8);
+ writer.WriteStringValue(PrincipalId.Value);
+ }
+ if (options.Format != "W" && Optional.IsDefined(TenantId))
+ {
+ writer.WritePropertyName("tenantId"u8);
+ writer.WriteStringValue(TenantId.Value);
+ }
+ writer.WritePropertyName("type"u8);
+ writer.WriteStringValue(SystemAssignedServiceIdentityType.ToString());
+ }
+
+ SystemAssignedServiceIdentity IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ var format = options.Format == "W" ? ((IPersistableModel