Skip to content

Commit 6589558

Browse files
committed
Make DefaultContainerRegistry required init
1 parent 90712e7 commit 6589558

File tree

6 files changed

+76
-109
lines changed

6 files changed

+76
-109
lines changed

src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppEnvironmentResource.cs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ await context.ReportingStep.CompleteAsync(
148148
/// </summary>
149149
internal BicepOutputReference ContainerAppDomain => new("AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN", this);
150150

151+
/// <summary>
152+
/// Gets the name of the associated Azure Container Registry.
153+
/// </summary>
154+
internal BicepOutputReference ContainerRegistryName => new("AZURE_CONTAINER_REGISTRY_NAME", this);
155+
151156
/// <summary>
152157
/// Gets the URL endpoint of the associated Azure Container Registry.
153158
/// </summary>
@@ -165,28 +170,14 @@ await context.ReportingStep.CompleteAsync(
165170

166171
internal Dictionary<string, (IResource resource, ContainerMountAnnotation volume, int index, BicepOutputReference outputReference)> VolumeNames { get; } = [];
167172

168-
internal AzureContainerRegistryResource? DefaultContainerRegistry { get; set; }
169-
170-
private IContainerRegistry GetAssociatedRegistry()
171-
{
172-
if (this.TryGetLastAnnotation<ContainerRegistryReferenceAnnotation>(out var annotation) &&
173-
annotation.Registry is IContainerRegistry registry)
174-
{
175-
return registry;
176-
}
177-
178-
if (DefaultContainerRegistry is not null)
179-
{
180-
return DefaultContainerRegistry;
181-
}
182-
183-
throw new InvalidOperationException($"No Azure container registry associated with environment '{Name}'");
184-
}
173+
/// <summary>
174+
/// Gets the default container registry for this environment.
175+
/// </summary>
176+
internal AzureContainerRegistryResource DefaultContainerRegistry { get; init; } = null!;
185177

186-
// Implement IAzureContainerRegistry interface by delegating to the associated registry
187-
ReferenceExpression IContainerRegistry.Name => GetAssociatedRegistry().Name;
178+
ReferenceExpression IContainerRegistry.Name => ReferenceExpression.Create($"{ContainerRegistryName}");
188179

189-
ReferenceExpression IContainerRegistry.Endpoint => GetAssociatedRegistry().Endpoint;
180+
ReferenceExpression IContainerRegistry.Endpoint => ReferenceExpression.Create($"{ContainerRegistryUrl}");
190181

191182
ReferenceExpression IAzureContainerRegistry.ManagedIdentityId => ReferenceExpression.Create($"{ContainerRegistryManagedIdentityId}");
192183

src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppExtensions.cs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon
5757
{
5858
builder.AddAzureContainerAppsInfrastructureCore();
5959

60+
// Create the default container registry resource before creating the environment
61+
var registryName = $"{name}-acr";
62+
var defaultRegistry = AzureContainerRegistryHelpers.CreateDefaultContainerRegistry(builder, registryName);
63+
6064
var containerAppEnvResource = new AzureContainerAppEnvironmentResource(name, static infra =>
6165
{
6266
var appEnvResource = (AzureContainerAppEnvironmentResource)infra.AspireResource;
@@ -325,12 +329,10 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> AddAzureCon
325329
{
326330
Value = containerAppEnvironment.DefaultDomain
327331
});
328-
});
329-
330-
// Create the default container registry resource without adding to the model
331-
var registryName = $"{containerAppEnvResource.Name}-acr";
332-
var defaultRegistry = CreateDefaultContainerRegistry(builder, registryName);
333-
containerAppEnvResource.DefaultContainerRegistry = defaultRegistry;
332+
})
333+
{
334+
DefaultContainerRegistry = defaultRegistry
335+
};
334336

335337
builder.Eventing.Subscribe<BeforeStartEvent>((data, token) =>
336338
{
@@ -398,32 +400,4 @@ public static IResourceBuilder<AzureContainerAppEnvironmentResource> WithAzureLo
398400

399401
return builder;
400402
}
401-
402-
private static AzureContainerRegistryResource CreateDefaultContainerRegistry(IDistributedApplicationBuilder builder, string name)
403-
{
404-
var configureInfrastructure = (AzureResourceInfrastructure infrastructure) =>
405-
{
406-
var registry = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
407-
(identifier, resourceName) =>
408-
{
409-
var resource = ContainerRegistryService.FromExisting(identifier);
410-
resource.Name = resourceName;
411-
return resource;
412-
},
413-
(infra) => new ContainerRegistryService(infra.AspireResource.GetBicepIdentifier())
414-
{
415-
Sku = new ContainerRegistrySku { Name = ContainerRegistrySkuName.Basic },
416-
Tags = { { "aspire-resource-name", infra.AspireResource.Name } }
417-
});
418-
419-
infrastructure.Add(registry);
420-
infrastructure.Add(new ProvisioningOutput("name", typeof(string)) { Value = registry.Name });
421-
infrastructure.Add(new ProvisioningOutput("loginServer", typeof(string)) { Value = registry.LoginServer });
422-
};
423-
424-
var resource = new AzureContainerRegistryResource(name, configureInfrastructure);
425-
builder.CreateResourceBuilder(resource);
426-
427-
return resource;
428-
}
429403
}

src/Aspire.Hosting.Azure.AppService/AzureAppServiceEnvironmentExtensions.cs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public static IResourceBuilder<AzureAppServiceEnvironmentResource> AddAzureAppSe
4444
{
4545
builder.AddAzureAppServiceInfrastructureCore();
4646

47+
// Create the default container registry resource before creating the environment
48+
var registryName = $"{name}-acr";
49+
var defaultRegistry = AzureContainerRegistryHelpers.CreateDefaultContainerRegistry(builder, registryName);
50+
4751
var resource = new AzureAppServiceEnvironmentResource(name, static infra =>
4852
{
4953
var prefix = infra.AspireResource.Name;
@@ -211,12 +215,10 @@ public static IResourceBuilder<AzureAppServiceEnvironmentResource> AddAzureAppSe
211215
Value = applicationInsights.ConnectionString
212216
});
213217
}
214-
});
215-
216-
// Create the default container registry resource without adding to the model
217-
var registryName = $"{resource.Name}-acr";
218-
var defaultRegistry = CreateDefaultContainerRegistry(builder, registryName);
219-
resource.DefaultContainerRegistry = defaultRegistry;
218+
})
219+
{
220+
DefaultContainerRegistry = defaultRegistry
221+
};
220222

221223
builder.Eventing.Subscribe<BeforeStartEvent>((data, token) =>
222224
{
@@ -309,32 +311,4 @@ public static IResourceBuilder<AzureAppServiceEnvironmentResource> WithAutomatic
309311
builder.Resource.EnableAutomaticScaling = true;
310312
return builder;
311313
}
312-
313-
private static AzureContainerRegistryResource CreateDefaultContainerRegistry(IDistributedApplicationBuilder builder, string name)
314-
{
315-
var configureInfrastructure = (AzureResourceInfrastructure infrastructure) =>
316-
{
317-
var registry = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
318-
(identifier, resourceName) =>
319-
{
320-
var resource = ContainerRegistryService.FromExisting(identifier);
321-
resource.Name = resourceName;
322-
return resource;
323-
},
324-
(infra) => new ContainerRegistryService(infra.AspireResource.GetBicepIdentifier())
325-
{
326-
Sku = new ContainerRegistrySku { Name = ContainerRegistrySkuName.Basic },
327-
Tags = { { "aspire-resource-name", infra.AspireResource.Name } }
328-
});
329-
330-
infrastructure.Add(registry);
331-
infrastructure.Add(new ProvisioningOutput("name", typeof(string)) { Value = registry.Name });
332-
infrastructure.Add(new ProvisioningOutput("loginServer", typeof(string)) { Value = registry.LoginServer });
333-
};
334-
335-
var resource = new AzureContainerRegistryResource(name, configureInfrastructure);
336-
builder.CreateResourceBuilder(resource);
337-
338-
return resource;
339-
}
340314
}

src/Aspire.Hosting.Azure.AppService/AzureAppServiceEnvironmentResource.cs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -203,31 +203,17 @@ await context.ReportingStep.CompleteAsync(
203203
internal static BicepValue<string> GetWebSiteSuffixBicep() =>
204204
BicepFunction.GetUniqueString(BicepFunction.GetResourceGroup().Id);
205205

206-
internal AzureContainerRegistryResource? DefaultContainerRegistry { get; set; }
206+
/// <summary>
207+
/// Gets the default container registry for this environment.
208+
/// </summary>
209+
internal AzureContainerRegistryResource DefaultContainerRegistry { get; init; } = null!;
207210

208-
private IContainerRegistry GetAssociatedRegistry()
209-
{
210-
if (this.TryGetLastAnnotation<ContainerRegistryReferenceAnnotation>(out var annotation) &&
211-
annotation.Registry is IContainerRegistry registry)
212-
{
213-
return registry;
214-
}
211+
ReferenceExpression IContainerRegistry.Name => ReferenceExpression.Create($"{ContainerRegistryName}");
215212

216-
if (DefaultContainerRegistry is not null)
217-
{
218-
return DefaultContainerRegistry;
219-
}
220-
221-
throw new InvalidOperationException($"No Azure container registry associated with environment '{Name}'");
222-
}
213+
ReferenceExpression IContainerRegistry.Endpoint => ReferenceExpression.Create($"{ContainerRegistryUrl}");
223214

224-
// Implement IAzureContainerRegistry interface by delegating to the associated registry
225215
ReferenceExpression IAzureContainerRegistry.ManagedIdentityId => ReferenceExpression.Create($"{ContainerRegistryManagedIdentityId}");
226216

227-
ReferenceExpression IContainerRegistry.Name => GetAssociatedRegistry().Name;
228-
229-
ReferenceExpression IContainerRegistry.Endpoint => GetAssociatedRegistry().Endpoint;
230-
231217
ReferenceExpression IComputeEnvironmentResource.GetHostAddressExpression(EndpointReference endpointReference)
232218
{
233219
var resource = endpointReference.Resource;

src/Aspire.Hosting.Azure.ContainerRegistry/Aspire.Hosting.Azure.ContainerRegistry.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
<Compile Include="$(RepoRoot)src\Shared\AzureRoleAssignmentUtils.cs" />
1212
</ItemGroup>
1313

14+
<ItemGroup>
15+
<InternalsVisibleTo Include="Aspire.Hosting.Azure.AppContainers" />
16+
<InternalsVisibleTo Include="Aspire.Hosting.Azure.AppService" />
17+
<InternalsVisibleTo Include="Aspire.Hosting.Azure.Tests" />
18+
</ItemGroup>
19+
1420
<ItemGroup>
1521
<ProjectReference Include="..\Aspire.Hosting.Azure\Aspire.Hosting.Azure.csproj" />
1622
<PackageReference Include="Azure.Provisioning" />

src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryHelpers.cs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,51 @@
99
using Aspire.Hosting.ApplicationModel;
1010
using Aspire.Hosting.Azure.Provisioning.Internal;
1111
using Aspire.Hosting.Pipelines;
12+
using Azure.Provisioning;
13+
using Azure.Provisioning.ContainerRegistry;
1214
using Microsoft.Extensions.DependencyInjection;
1315

1416
namespace Aspire.Hosting.Azure;
1517

1618
/// <summary>
17-
/// Helper methods for Azure Container Registry login operations.
19+
/// Helper methods for Azure Container Registry operations.
1820
/// </summary>
1921
internal static class AzureContainerRegistryHelpers
2022
{
23+
/// <summary>
24+
/// Creates a default Azure Container Registry resource without adding it to the model.
25+
/// </summary>
26+
/// <param name="builder">The distributed application builder.</param>
27+
/// <param name="name">The name of the container registry resource.</param>
28+
/// <returns>The created <see cref="AzureContainerRegistryResource"/>.</returns>
29+
public static AzureContainerRegistryResource CreateDefaultContainerRegistry(IDistributedApplicationBuilder builder, string name)
30+
{
31+
var configureInfrastructure = (AzureResourceInfrastructure infrastructure) =>
32+
{
33+
var registry = AzureProvisioningResource.CreateExistingOrNewProvisionableResource(infrastructure,
34+
(identifier, resourceName) =>
35+
{
36+
var resource = ContainerRegistryService.FromExisting(identifier);
37+
resource.Name = resourceName;
38+
return resource;
39+
},
40+
(infra) => new ContainerRegistryService(infra.AspireResource.GetBicepIdentifier())
41+
{
42+
Sku = new ContainerRegistrySku { Name = ContainerRegistrySkuName.Basic },
43+
Tags = { { "aspire-resource-name", infra.AspireResource.Name } }
44+
});
45+
46+
infrastructure.Add(registry);
47+
infrastructure.Add(new ProvisioningOutput("name", typeof(string)) { Value = registry.Name });
48+
infrastructure.Add(new ProvisioningOutput("loginServer", typeof(string)) { Value = registry.LoginServer });
49+
};
50+
51+
var resource = new AzureContainerRegistryResource(name, configureInfrastructure);
52+
builder.CreateResourceBuilder(resource);
53+
54+
return resource;
55+
}
56+
2157
public static async Task LoginToRegistryAsync(IContainerRegistry registry, PipelineStepContext context)
2258
{
2359
var acrLoginService = context.Services.GetRequiredService<IAcrLoginService>();

0 commit comments

Comments
 (0)