@@ -37,8 +37,36 @@ public static class AzureFunctionsProjectResourceExtensions
3737 if ( item . HostStorage == storage )
3838 {
3939 removeStorage = false ;
40- break ;
4140 }
41+
42+ // Before the resource starts, we want to apply the azure functions specific environment variables.
43+ // we look at all of the environment variables and apply the configuration for any resources that implement IResourceWithAzureFunctionsConfig.
44+ item . Annotations . Add ( new EnvironmentCallbackAnnotation ( static context =>
45+ {
46+ var functionsConfigMapping = new Dictionary < string , IResourceWithAzureFunctionsConfig > ( ) ;
47+
48+ foreach ( var ( _, val ) in context . EnvironmentVariables )
49+ {
50+ var ( name , config ) = val switch
51+ {
52+ IResourceWithAzureFunctionsConfig c => ( c . Name , c ) ,
53+ ConnectionStringReference conn when conn . Resource is IResourceWithAzureFunctionsConfig c => ( conn . ConnectionName ?? c . Name , c ) ,
54+ _ => ( "" , null )
55+ } ;
56+
57+ if ( config is not null )
58+ {
59+ functionsConfigMapping [ name ] = config ;
60+ }
61+ }
62+
63+ foreach ( var ( name , config ) in functionsConfigMapping )
64+ {
65+ config . ApplyAzureFunctionsConfiguration ( context . EnvironmentVariables , name ) ;
66+ }
67+
68+ return Task . CompletedTask ;
69+ } ) ) ;
4270 }
4371
4472 if ( removeStorage )
@@ -52,7 +80,7 @@ public static class AzureFunctionsProjectResourceExtensions
5280
5381 resource . HostStorage = storage ;
5482
55- var functionsBuilder = builder . AddResource ( resource )
83+ return builder . AddResource ( resource )
5684 . WithArgs ( context =>
5785 {
5886 var http = resource . GetEndpoint ( "http" ) ;
@@ -104,8 +132,6 @@ public static class AzureFunctionsProjectResourceExtensions
104132
105133 context . Writer . WriteEndObject ( ) ;
106134 } ) ;
107-
108- return functionsBuilder ;
109135 }
110136
111137 /// <summary>
@@ -119,79 +145,4 @@ public static IResourceBuilder<AzureFunctionsProjectResource> WithHostStorage(th
119145 builder . Resource . HostStorage = storage . Resource ;
120146 return builder ;
121147 }
122-
123- /// <remarks>
124- /// This implementation demonstrates the approach of "teaching Aspire about Functions" where we take advantage of
125- /// Aspire's ConnectionStringExpression to map to the connection strings format that Azure Functions understands.
126- /// An alternative approach here is to "teach Functions about Aspire" where integrate the Aspire configuration
127- /// model into the Azure Functions worker extensions.
128- /// </remarks>
129- #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
130- public static IResourceBuilder < AzureFunctionsProjectResource > WithReference ( this IResourceBuilder < AzureFunctionsProjectResource > builder , IResourceBuilder < AzureQueueStorageResource > source , string ? connectionName = null )
131- #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
132- {
133- return builder . WithEnvironment ( context =>
134- {
135- connectionName ??= source . Resource . Name ;
136- if ( source . Resource . Parent . IsEmulator )
137- {
138- context . EnvironmentVariables [ connectionName ] = source . Resource . Parent . GetEmulatorConnectionString ( ) ;
139- }
140- else
141- {
142- context . EnvironmentVariables [ $ "{ connectionName } __queueServiceUri"] = source . Resource . ConnectionStringExpression ;
143- }
144- } ) ;
145- }
146-
147- /// <summary>
148- ///
149- /// </summary>
150- /// <param name="builder"></param>
151- /// <param name="source"></param>
152- /// <param name="connectionName"></param>
153- /// <returns></returns>
154- #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
155- public static IResourceBuilder < AzureFunctionsProjectResource > WithReference ( this IResourceBuilder < AzureFunctionsProjectResource > builder , IResourceBuilder < AzureBlobStorageResource > source , string ? connectionName = null )
156- #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
157- {
158- return builder . WithEnvironment ( context =>
159- {
160- connectionName ??= source . Resource . Name ;
161-
162- if ( source . Resource . Parent . IsEmulator )
163- {
164- context . EnvironmentVariables [ connectionName ] = source . Resource . Parent . GetEmulatorConnectionString ( ) ;
165- }
166- else
167- {
168- context . EnvironmentVariables [ $ "{ connectionName } __blobServiceUri"] = source . Resource . ConnectionStringExpression ;
169- }
170- } ) ;
171- }
172-
173- /// <summary>
174- ///
175- /// </summary>
176- /// <param name="builder"></param>
177- /// <param name="source"></param>
178- /// <param name="connectionName"></param>
179- /// <returns></returns>
180- #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
181- public static IResourceBuilder < AzureFunctionsProjectResource > WithReference ( this IResourceBuilder < AzureFunctionsProjectResource > builder , IResourceBuilder < AzureEventHubsResource > source , string ? connectionName = null )
182- #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
183- {
184- return builder . WithEnvironment ( context =>
185- {
186- connectionName ??= source . Resource . Name ;
187- if ( source . Resource . IsEmulator )
188- {
189- context . EnvironmentVariables [ connectionName ] = source . Resource . ConnectionStringExpression ;
190- }
191- else
192- {
193- context . EnvironmentVariables [ $ "{ connectionName } __fullyQualifiedNamespace"] = source . Resource . ConnectionStringExpression ;
194- }
195- } ) ;
196- }
197148}
0 commit comments