{"record":{"id":"77ab4d691a2edae7","repo":"microsoft/aspire","slug":"provisionableconstruct-defineproperty-t-not-found-via","errorCode":null,"errorMessage":"ProvisionableConstruct.DefineProperty<T> not found via reflection. The Azure.Provisioning surface may have changed; review AksPreviewIngressProfileInjector.","messagePattern":"ProvisionableConstruct\\.DefineProperty<T> not found via reflection\\. The Azure\\.Provisioning surface may have changed; review AksPreviewIngressProfileInjector\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.Kubernetes/AksPreviewIngressProfileInjector.cs","lineNumber":95,"sourceCode":"/// <para>\n/// Tracked by <see href=\"https://github.com/microsoft/aspire/issues/17060\"/> (Aspire) and\n/// <see href=\"https://github.com/Azure/azure-sdk-for-net/issues/59225\"/> (upstream).\n/// </para>\n/// </remarks>\n// TODO: https://github.com/microsoft/aspire/issues/17060 - delete this class once\n// Azure.Provisioning.ContainerService exposes ManagedClusterIngressProfile publicly\n// with typed GatewayApi and ApplicationLoadBalancer properties.\ninternal static class AksPreviewIngressProfileInjector\n{\n    private const string IngressProfileTypeFullName = \"Azure.Provisioning.ContainerService.ManagedClusterIngressProfile\";\n\n    private static readonly Lazy<MethodInfo> s_defineProperty = new(() =>\n    {\n        // protected BicepValue<T> DefineProperty<T>(string propertyName, string[] bicepPath, bool isOutput = false, bool isRequired = false, bool isSecure = false, BicepValue<T>? defaultValue = null, string? format = null)\n        return typeof(ProvisionableConstruct).GetMethod(\n            \"DefineProperty\",\n            BindingFlags.NonPublic | BindingFlags.Instance)\n            ?? throw new InvalidOperationException(\"ProvisionableConstruct.DefineProperty<T> not found via reflection. The Azure.Provisioning surface may have changed; review AksPreviewIngressProfileInjector.\");\n    });\n\n    /// <summary>\n    /// Injects the requested preview-only ingressProfile entries onto <paramref name=\"aks\"/>.\n    /// Caller is responsible for setting an appropriate preview <c>ResourceVersion</c> on\n    /// the cluster (e.g. <c>2025-09-02-preview</c>) before any properties are compiled.\n    /// </summary>\n    public static void Inject(ContainerServiceManagedCluster aks, bool gatewayApi, bool applicationLoadBalancer)\n    {\n        if (!gatewayApi && !applicationLoadBalancer)\n        {\n            return;\n        }\n\n        // Bootstrap the lazily-created internal IngressProfile by assigning an empty\n        // WebAppRouting object via the public setter. An empty WebAppRouting object is\n        // filtered out at emission time, so this does not introduce a stray webAppRouting\n        // entry into the rendered Bicep.","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.Kubernetes/AksPreviewIngressProfileInjector.cs#L77-L113","documentation":"AksPreviewIngressProfileInjector locates the protected generic ProvisionableConstruct.DefineProperty<T> method via reflection to emit preview-only AKS ingressProfile Bicep properties. This error is thrown from the static Lazy initializer when GetMethod(\"DefineProperty\", NonPublic|Instance) returns null, meaning the Azure.Provisioning assembly no longer contains a method with that exact name/signature binding — a package-version drift guard.","triggerScenarios":"Upgrading Azure.Provisioning (Azure.Provisioning.ContainerService) to a version that renamed, removed, or changed the binding flags/overload resolution of DefineProperty<T> on ProvisionableConstruct, then building/publishing an app model that enables Gateway API or Application Load Balancer on an AKS cluster (Inject is called, and s_defineProperty.Value is first evaluated).","commonSituations":"Central package management bumps Azure.Provisioning.* to a newer beta; a transitive dependency pulls a different Azure.Provisioning major; MAUI/SDK unification changes binding behavior; upgrading Aspire against a newer azure-sdk-for-net beta where the reflection contract broke.","solutions":["Pin Azure.Provisioning.ContainerService to a version known to work (1.0.0-beta.6 or the version Aspire was built against) via Directory.Packages.props","Check the new Azure.Provisioning source for DefineProperty's current name/signature and update the reflection lookup in AksPreviewIngressProfileInjector (or the public-subclass replacement if ManagedClusterIngressProfile is now public)","Clear stale package caches and restore to ensure the expected assembly version is actually bound (bind redirects / transitive downgrades)","Track microsoft/aspire#17060 and Azure/azure-sdk-for-net#59225 — when the typed API ships upstream, remove the reflection path"],"exampleFix":"// before\nreturn typeof(ProvisionableConstruct).GetMethod(\"DefineProperty\", BindingFlags.NonPublic | BindingFlags.Instance)\n    ?? throw new InvalidOperationException(\"...DefineProperty<T> not found...\");\n// after (if upstream renamed/overloaded it)\nreturn typeof(ProvisionableConstruct).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)\n    .Single(m => m.Name == \"DefineProperty\" && m.IsGenericMethodDefinition)\n    ?? throw new InvalidOperationException(\"...DefineProperty<T> not found...\");","handlingStrategy":"fallback","validationCode":"var defineProperty = typeof(ProvisionableConstruct).GetMethod(\"DefineProperty\",\n    BindingFlags.NonPublic | BindingFlags.Instance);\nif (defineProperty is null)\n{\n    // Pre-flight check before enabling preview ingress features.\n    throw new InvalidOperationException(\"Installed Azure.Provisioning version is incompatible with AKS preview ingress injection; pin Azure.Provisioning.ContainerService 1.0.0-beta.6.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    AksPreviewIngressProfileInjector.Inject(aks, gatewayApi: true, applicationLoadBalancer: false);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"DefineProperty\"))\n{\n    // Package drift: surface the resolved Azure.Provisioning version in the message.\n    throw new InvalidOperationException($\"Azure.Provisioning version mismatch (DefineProperty missing). Verify the pinned package version.\", ex);\n}","preventionTips":["Pin Azure.Provisioning.* versions in Directory.Packages.props instead of floating","Check azure-sdk-for-net release notes for ProvisionableConstruct API changes before upgrading","Run a publish/Bicep-generation test whenever the provisioning package version changes","Add a unit test that touches s_defineProperty.Value early so drift fails in tests, not at user publish time","Track aspire#17060 / Azure#59225 and migrate to the typed API when available"],"tags":["reflection","azure","aks","azure-provisioning","version-incompatibility"],"backgroundTag":"class-not-found","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}