Skip to content

Commit 0015d16

Browse files
Upgraded Azrue Function Program file to support IProgramFileTempalte
Upgraded KeyVault to work with Azure Functions.
1 parent 09a60ba commit 0015d16

File tree

6 files changed

+185
-11
lines changed

6 files changed

+185
-11
lines changed

Modules/Intent.Modules.Azure.KeyVault/FactoryExtensions/ProgramExtension.cs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Linq;
23
using Intent.Engine;
34
using Intent.Modules.Azure.KeyVault.Templates.AzureKeyVaultConfiguration;
@@ -26,14 +27,52 @@ public class ProgramExtension : FactoryExtensionBase
2627
[IntentManaged(Mode.Ignore)] public override int Order => 0;
2728

2829
protected override void OnAfterTemplateRegistrations(IApplication application)
30+
{
31+
DoAspNetCoreProgramFile(application);
32+
DoAzureFunctionsProgramFile(application);
33+
}
34+
35+
private void DoAzureFunctionsProgramFile(IApplication application)
36+
{
37+
var programTemplate = application.FindTemplateInstance<IProgramTemplate>(TemplateDependency.OnTemplate("Intent.AzureFunctions.Isolated.Program"));
38+
if (programTemplate == null)
39+
{
40+
return;
41+
}
42+
43+
var configTemplate = application.FindTemplateInstance<ICSharpFileBuilderTemplate>(AzureKeyVaultConfigurationTemplate.TemplateId, programTemplate.OutputTarget);
44+
if (configTemplate == null)
45+
{
46+
return;
47+
}
48+
49+
programTemplate.CSharpFile.OnBuild(file =>
50+
{
51+
file.AddUsing(configTemplate.Namespace);
52+
file.AddUsing("Microsoft.Extensions.Configuration");
53+
54+
programTemplate.ProgramFile.ConfigureAppConfiguration(true, (statements, parameters) =>
55+
{
56+
statements.AddStatement($"var built = {parameters[^1]}.Build();");
57+
statements.AddIfStatement(@"built.GetValue<bool?>(""KeyVault:Enabled"") == true", @if =>
58+
{
59+
@if.AddStatement($"{parameters[^1]}.ConfigureAzureKeyVault(built);");
60+
});
61+
}, -10);
62+
63+
}, 30);
64+
65+
}
66+
67+
private static void DoAspNetCoreProgramFile(IApplication application)
2968
{
3069
var programTemplate = application.FindTemplateInstance<IProgramTemplate>(TemplateDependency.OnTemplate("App.Program"));
3170
if (programTemplate == null)
3271
{
3372
return;
3473
}
3574

36-
var configTemplate = application.FindTemplateInstance<ICSharpFileBuilderTemplate>(TemplateDependency.OnTemplate(AzureKeyVaultConfigurationTemplate.TemplateId));
75+
var configTemplate = application.FindTemplateInstance<ICSharpFileBuilderTemplate>(AzureKeyVaultConfigurationTemplate.TemplateId, programTemplate.OutputTarget);
3776
if (configTemplate == null)
3877
{
3978
return;

Modules/Intent.Modules.Azure.KeyVault/Intent.Azure.KeyVault.imodspec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<package>
33
<id>Intent.Azure.KeyVault</id>
4-
<version>2.0.14</version>
4+
<version>2.0.15-pre.0</version>
55
<supportedClientVersions>[4.3.0-a, 5.0.0-a)</supportedClientVersions>
66
<summary>Extend .NET Configuration with Secrets stored in Azure Key Vault.</summary>
77
<description>Extend .NET Configuration with Secrets stored in Azure Key Vault.</description>
@@ -32,6 +32,11 @@
3232
<package id="Intent.AspNetCore" version="6.0.2" />
3333
</install>
3434
</detect>
35+
<detect id="Intent.AzureFunctions">
36+
<install>
37+
<package id="Intent.AzureFunctions" version="5.0.17-pre.0" />
38+
</install>
39+
</detect>
3540
<!-- /Minimum Compatible Versions -->
3641
</interoperability>
3742
<dependencies>

Modules/Intent.Modules.Azure.KeyVault/Intent.Modules.Azure.KeyVault.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Intent.Modules.Common" Version="3.7.2" />
9+
<PackageReference Include="Intent.Modules.Common" Version="3.9.0" />
1010
<PackageReference Include="Intent.Modules.Common.CSharp" Version="3.8.1" />
1111
<PackageReference Include="Intent.Packager" Version="3.5.0">
1212
<PrivateAssets>all</PrivateAssets>
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>
1515
<PackageReference Include="Intent.RoslynWeaver.Attributes" Version="2.1.7" />
16-
<PackageReference Include="Intent.SoftwareFactory.SDK" Version="3.7.0" />
16+
<PackageReference Include="Intent.SoftwareFactory.SDK" Version="3.10.0-pre.2" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

Modules/Intent.Modules.AzureFunctions/Intent.AzureFunctions.imodspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<package>
33
<id>Intent.AzureFunctions</id>
4-
<version>5.0.16</version>
4+
<version>5.0.17-pre.0</version>
55
<supportedClientVersions>[4.5.15-a, 5.0.0-a)</supportedClientVersions>
66
<summary>Provides support to describe Azure Functions in the Services designer</summary>
77
<description>Provides support to describe Azure Functions in the Services designer</description>

Modules/Intent.Modules.AzureFunctions/Intent.Modules.AzureFunctions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
5-
<PackageVersion>5.0.16</PackageVersion>
5+
<PackageVersion>5.0.17-pre.0</PackageVersion>
66
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
77
<PackageIcon>logo.png</PackageIcon>
88
<Authors>Intent Architect</Authors>

Modules/Intent.Modules.AzureFunctions/Templates/Isolated/Program/ProgramTemplatePartial.cs

Lines changed: 135 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
namespace Intent.Modules.AzureFunctions.Templates.Isolated.Program
2626
{
2727
[IntentManaged(Mode.Fully, Body = Mode.Merge)]
28-
public partial class ProgramTemplate : CSharpTemplateBase<object>, ICSharpFileBuilderTemplate
28+
public partial class ProgramTemplate : CSharpTemplateBase<object>, ICSharpFileBuilderTemplate, IProgramTemplate, IProgramFile
2929
{
3030
public const string TemplateId = "Intent.AzureFunctions.Isolated.Program";
3131

@@ -131,16 +131,16 @@ public ProgramTemplate(IOutputTarget outputTarget, object model = null) : base(T
131131
globalExceptionConfigStatement.AddStatement<CSharpLambdaBlock, CSharpStatement>(globalExceptionStatement);
132132
}
133133

134-
var hostConfigStatement = new CSharpStatement("new HostBuilder()")
135-
.AddInvocation("ConfigureFunctionsWebApplication", i => i
134+
var hostConfigStatement = new CSharpMethodChainStatement("new HostBuilder()")
135+
.AddChainStatement( new CSharpInvocationStatement( "ConfigureFunctionsWebApplication").WithoutSemicolon()
136136
.OnNewLine()
137137
.AddArgument(globalExceptionConfigStatement)
138138
)
139-
.AddInvocation("ConfigureServices", cs => cs
139+
.AddChainStatement(new CSharpInvocationStatement("ConfigureServices").WithoutSemicolon()
140140
.OnNewLine()
141141
.AddArgument(configStatements)
142142
)
143-
.AddInvocation("Build", i => i.OnNewLine());
143+
.AddChainStatement(new CSharpInvocationStatement("Build").OnNewLine());
144144

145145
tls.AddStatement(new CSharpAssignmentStatement("var host", hostConfigStatement));
146146
tls.AddStatement("host.Run();", s => s.SeparatedFromPrevious());
@@ -496,6 +496,10 @@ private record ServiceConfigurationContext(string Configuration, string Services
496496
[IntentManaged(Mode.Fully)]
497497
public CSharpFile CSharpFile { get; }
498498

499+
public bool UsesMinimalHostingModel => true;
500+
501+
public IProgramFile ProgramFile => this;
502+
499503
[IntentManaged(Mode.Fully)]
500504
protected override CSharpFileConfig DefineFileConfig()
501505
{
@@ -507,5 +511,131 @@ public override string TransformText()
507511
{
508512
return CSharpFile.ToString();
509513
}
514+
515+
public IProgramFile ConfigureHostBuilderChainStatement(string methodName, IEnumerable<string> parameters, IProgramFile.HostBuilderChainStatementConfiguration configure = null, int priority = 0)
516+
{
517+
var parametersAsArray = parameters.ToArray();
518+
519+
var hostBuilder = (IHasCSharpStatements?)CSharpFile.TopLevelStatements.Statements.FirstOrDefault();
520+
521+
var hostBuilderChain = (CSharpMethodChainStatement)((CSharpAssignmentStatement)hostBuilder).Rhs;
522+
var appConfigurationBlock = (CSharpInvocationStatement)hostBuilderChain
523+
.FindStatement(stmt => stmt.ToString()!.StartsWith(methodName));
524+
525+
var lambda = EnsureWeHaveEditableLambdaBlock(appConfigurationBlock);
526+
527+
if (appConfigurationBlock == null)
528+
{
529+
lambda = new EditableCSharpLambdaBlock("()");
530+
531+
appConfigurationBlock = new CSharpInvocationStatement(methodName)
532+
.WithoutSemicolon()
533+
.AddArgument(lambda);
534+
appConfigurationBlock.AddMetadata("priority", priority);
535+
536+
537+
var insertAboveStatement = hostBuilderChain.Statements.FirstOrDefault(s =>
538+
{
539+
if (s.TryGetMetadata<int>("priority", out var statmentPriority))
540+
{
541+
return statmentPriority > priority;
542+
}
543+
else
544+
{
545+
return priority < 0;
546+
}
547+
});
548+
if (insertAboveStatement == null)
549+
{
550+
insertAboveStatement = hostBuilderChain.Statements.Last();
551+
}
552+
insertAboveStatement.InsertAbove(appConfigurationBlock);
553+
}
554+
555+
SetParameters(lambda, parametersAsArray);
556+
configure?.Invoke(lambda, (IReadOnlyList<string>)lambda.Metadata["parameters"]);
557+
return this;
558+
}
559+
560+
static void SetParameters(EditableCSharpLambdaBlock lambda, IReadOnlyList<string> requestedParameters)
561+
{
562+
if (!lambda.TryGetMetadata<List<string>>("parameters", out var parameters))
563+
{
564+
parameters = new List<string>();
565+
lambda.AddMetadata("parameters", parameters);
566+
}
567+
568+
if (parameters.Count >= requestedParameters.Count)
569+
{
570+
return;
571+
}
572+
573+
parameters.AddRange(requestedParameters.Skip(parameters.Count));
574+
575+
lambda.UpdateText(parameters.Count == 1
576+
? parameters[0]
577+
: $"({string.Join(", ", parameters)})");
578+
}
579+
580+
581+
public IProgramFile AddHostBuilderConfigurationStatement<TStatement>(TStatement statement, Action<TStatement> configure = null, int priority = 0) where TStatement : CSharpStatement
582+
{
583+
throw new NotImplementedException();
584+
}
585+
586+
public IProgramFile ConfigureMainStatementsBlock(Action<IHasCSharpStatements> configure)
587+
{
588+
throw new NotImplementedException();
589+
}
590+
591+
public IProgramFile AddMethod(string returnType, string name, Action<IStartupMethod> configure = null, int priority = 0)
592+
{
593+
throw new NotImplementedException();
594+
}
595+
596+
static EditableCSharpLambdaBlock EnsureWeHaveEditableLambdaBlock(CSharpInvocationStatement appConfigurationBlock)
597+
{
598+
EditableCSharpLambdaBlock? lambda;
599+
var configBlockStatement = appConfigurationBlock?.Statements.First();
600+
if (configBlockStatement is CSharpLambdaBlock lambdaConfig and not EditableCSharpLambdaBlock)
601+
{
602+
lambda = EditableCSharpLambdaBlock.CreateFrom(lambdaConfig);
603+
appConfigurationBlock!.Statements.RemoveAt(0);
604+
appConfigurationBlock.AddArgument(lambda);
605+
}
606+
else
607+
{
608+
lambda = (EditableCSharpLambdaBlock?)appConfigurationBlock?.Statements.First();
609+
}
610+
611+
return lambda;
612+
}
613+
614+
615+
private class EditableCSharpLambdaBlock : CSharpLambdaBlock
616+
{
617+
public EditableCSharpLambdaBlock(string invocation) : base(invocation) { }
618+
619+
public void UpdateText(string text) => Text = text;
620+
621+
public static EditableCSharpLambdaBlock CreateFrom(CSharpLambdaBlock original)
622+
{
623+
var update = new EditableCSharpLambdaBlock(original.Text);
624+
if (original.HasExpressionBody)
625+
{
626+
update.WithExpressionBody(original.Statements.First());
627+
}
628+
else
629+
{
630+
foreach (var statement in original.Statements)
631+
{
632+
update.Statements.Add(statement);
633+
}
634+
}
635+
636+
return update;
637+
}
638+
}
639+
510640
}
511641
}

0 commit comments

Comments
 (0)