diff --git a/.doc_gen/metadata/redshift_metadata.yaml b/.doc_gen/metadata/redshift_metadata.yaml
index d9627603d72..fad23ba02fa 100644
--- a/.doc_gen/metadata/redshift_metadata.yaml
+++ b/.doc_gen/metadata/redshift_metadata.yaml
@@ -5,6 +5,14 @@ redshift_Hello:
synopsis: get started using &RS;.
category: Hello
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.Hello
Go:
versions:
- sdk_version: 2
@@ -35,6 +43,14 @@ redshift_Hello:
redshift: {DescribeClusters}
redshift_ListDatabases:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.ListDatabases
Java:
versions:
- sdk_version: 2
@@ -48,6 +64,14 @@ redshift_ListDatabases:
redshift: {ListDatabases}
redshift_CreateCluster:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.CreateCluster
Go:
versions:
- sdk_version: 2
@@ -105,6 +129,14 @@ redshift_CreateCluster:
redshift: {CreateCluster}
redshift_DeleteCluster:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.DeleteCluster
Go:
versions:
- sdk_version: 2
@@ -162,6 +194,14 @@ redshift_DeleteCluster:
redshift: {DeleteCluster}
redshift_DescribeClusters:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.DescribeClusters
Go:
versions:
- sdk_version: 2
@@ -219,6 +259,14 @@ redshift_DescribeClusters:
redshift: {DescribeClusters}
redshift_ModifyCluster:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.ModifyCluster
Go:
versions:
- sdk_version: 2
@@ -276,6 +324,14 @@ redshift_ModifyCluster:
redshift: {ModifyCluster}
redshift_DescribeStatement:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.DescribeStatement
Java:
versions:
- sdk_version: 2
@@ -302,6 +358,14 @@ redshift_DescribeStatement:
redshift: {DescribeStatement}
redshift_GetStatementResult:
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description:
+ snippet_tags:
+ - Redshift.dotnetv4.GetStatementResult
Java:
versions:
- sdk_version: 2
@@ -356,6 +420,17 @@ redshift_Scenario:
- Delete the Amazon Redshift cluster.
category: Basics
languages:
+ .NET:
+ versions:
+ - sdk_version: 4
+ github: dotnetv4/Redshift
+ excerpts:
+ - description: Create a Redshift wrapper class to manage operations.
+ snippet_tags:
+ - Redshift.dotnetv4.RedshiftWrapper
+ - description: Run an interactive scenario demonstrating Redshift basics.
+ snippet_tags:
+ - Redshift.dotnetv4.RedshiftScenario
Go:
versions:
- sdk_version: 2
diff --git a/dotnetv4/DotNetV4Examples.sln b/dotnetv4/DotNetV4Examples.sln
index e4e1cf6f809..820afe0cfbe 100644
--- a/dotnetv4/DotNetV4Examples.sln
+++ b/dotnetv4/DotNetV4Examples.sln
@@ -63,7 +63,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Command_R_InvokeModelWithRe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Command_R_InvokeModel", "Bedrock-runtime\Models\CohereCommand\Command_R_InvokeModel\Command_R_InvokeModel.csproj", "{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}"
EndProject
-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AnthropicClaude", "AnthropicClaude", "{6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvokeModelWithResponseStream", "Bedrock-runtime\Models\AnthropicClaude\InvokeModelWithResponseStream\InvokeModelWithResponseStream.csproj", "{345DA0D1-C762-49EF-9953-6F4D57CB7FC7}"
@@ -76,7 +75,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Converse", "Bedrock-runtime
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AmazonTitanText", "AmazonTitanText", "{74979310-8A92-47DC-B5CA-EFA7970E1202}"
EndProject
-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BedrockRuntimeActions", "Bedrock-runtime\Actions\BedrockRuntimeActions.csproj", "{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CloudFormation", "CloudFormation", "{5FBEAD92-9234-4824-9320-2052D236C9CD}"
@@ -147,206 +145,636 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scenarios", "Scenarios", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Basics", "S3\Scenarios\S3_CreatePresignedPost\Basics.csproj", "{2B6F24A0-4569-E8A2-81B4-3925FA4F0320}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Redshift", "Redshift", "{BC1690DE-FD9E-72EA-CAED-A2B9A3D6B335}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedshiftActions", "Redshift\Actions\RedshiftActions.csproj", "{4E74F2DB-3BA5-4390-8FBF-C58F57601671}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedshiftBasics", "Redshift\Scenarios\RedshiftBasics.csproj", "{A30F8E57-AF18-40EC-B130-140585246CC7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedshiftTests", "Redshift\Tests\RedshiftTests.csproj", "{1DB37AC5-18FE-4535-816C-827B4D3DCB96}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|x64.Build.0 = Debug|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Debug|x86.Build.0 = Debug|Any CPU
{44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|x64.ActiveCfg = Release|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|x64.Build.0 = Release|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|x86.ActiveCfg = Release|Any CPU
+ {44801438-44F3-4B57-8A5E-3C788A9B2686}.Release|x86.Build.0 = Release|Any CPU
{67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|x64.Build.0 = Debug|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Debug|x86.Build.0 = Debug|Any CPU
{67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|x64.ActiveCfg = Release|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|x64.Build.0 = Release|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|x86.ActiveCfg = Release|Any CPU
+ {67C93719-C71C-44C3-8677-BF9C7CD093B6}.Release|x86.Build.0 = Release|Any CPU
{33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|x64.Build.0 = Debug|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Debug|x86.Build.0 = Debug|Any CPU
{33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|x64.ActiveCfg = Release|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|x64.Build.0 = Release|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|x86.ActiveCfg = Release|Any CPU
+ {33E362E5-40F3-4C90-A229-44EF3E2389EF}.Release|x86.Build.0 = Release|Any CPU
{28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|x64.Build.0 = Debug|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Debug|x86.Build.0 = Debug|Any CPU
{28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|Any CPU.Build.0 = Release|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|x64.ActiveCfg = Release|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|x64.Build.0 = Release|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|x86.ActiveCfg = Release|Any CPU
+ {28C9796E-9E28-4715-BD44-82CCF4BF8797}.Release|x86.Build.0 = Release|Any CPU
{96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|x64.Build.0 = Debug|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Debug|x86.Build.0 = Debug|Any CPU
{96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|x64.ActiveCfg = Release|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|x64.Build.0 = Release|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|x86.ActiveCfg = Release|Any CPU
+ {96B016E8-CDB3-490B-A1BB-6A9008E9E30B}.Release|x86.Build.0 = Release|Any CPU
{18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|x64.Build.0 = Debug|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Debug|x86.Build.0 = Debug|Any CPU
{18B07F62-06CC-4562-BB86-2C072758B90F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18B07F62-06CC-4562-BB86-2C072758B90F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Release|x64.ActiveCfg = Release|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Release|x64.Build.0 = Release|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Release|x86.ActiveCfg = Release|Any CPU
+ {18B07F62-06CC-4562-BB86-2C072758B90F}.Release|x86.Build.0 = Release|Any CPU
{F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|x64.Build.0 = Debug|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Debug|x86.Build.0 = Debug|Any CPU
{F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|x64.ActiveCfg = Release|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|x64.Build.0 = Release|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|x86.ActiveCfg = Release|Any CPU
+ {F98B4D67-5A92-4D66-9DAA-8334D65E23B1}.Release|x86.Build.0 = Release|Any CPU
{C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|x64.Build.0 = Debug|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Debug|x86.Build.0 = Debug|Any CPU
{C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|x64.ActiveCfg = Release|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|x64.Build.0 = Release|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|x86.ActiveCfg = Release|Any CPU
+ {C1A6A3FD-5ADD-4489-92E3-D888F256B74A}.Release|x86.Build.0 = Release|Any CPU
{F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|x64.Build.0 = Debug|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Debug|x86.Build.0 = Debug|Any CPU
{F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|x64.ActiveCfg = Release|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|x64.Build.0 = Release|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|x86.ActiveCfg = Release|Any CPU
+ {F8B5BC77-F8BF-45E8-8E12-7E197F925772}.Release|x86.Build.0 = Release|Any CPU
{37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|x64.Build.0 = Debug|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Debug|x86.Build.0 = Debug|Any CPU
{37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|x64.ActiveCfg = Release|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|x64.Build.0 = Release|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|x86.ActiveCfg = Release|Any CPU
+ {37CACA7D-D3BE-42AF-A8C2-639E16C03BC4}.Release|x86.Build.0 = Release|Any CPU
{7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|x64.Build.0 = Debug|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Debug|x86.Build.0 = Debug|Any CPU
{7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|x64.ActiveCfg = Release|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|x64.Build.0 = Release|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|x86.ActiveCfg = Release|Any CPU
+ {7B624438-4340-4333-B2F6-2ADA7A93006C}.Release|x86.Build.0 = Release|Any CPU
{F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|x64.Build.0 = Debug|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Debug|x86.Build.0 = Debug|Any CPU
{F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|x64.ActiveCfg = Release|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|x64.Build.0 = Release|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|x86.ActiveCfg = Release|Any CPU
+ {F60B3806-CC22-470E-80EE-2E480912CE4D}.Release|x86.Build.0 = Release|Any CPU
{E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|x64.Build.0 = Debug|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Debug|x86.Build.0 = Debug|Any CPU
{E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|x64.ActiveCfg = Release|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|x64.Build.0 = Release|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|x86.ActiveCfg = Release|Any CPU
+ {E264ABD1-EDC9-4E8E-B828-9CA239792051}.Release|x86.Build.0 = Release|Any CPU
{44E0145A-684C-466D-8258-171AF9751D95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44E0145A-684C-466D-8258-171AF9751D95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Debug|x64.Build.0 = Debug|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Debug|x86.Build.0 = Debug|Any CPU
{44E0145A-684C-466D-8258-171AF9751D95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44E0145A-684C-466D-8258-171AF9751D95}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Release|x64.ActiveCfg = Release|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Release|x64.Build.0 = Release|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Release|x86.ActiveCfg = Release|Any CPU
+ {44E0145A-684C-466D-8258-171AF9751D95}.Release|x86.Build.0 = Release|Any CPU
{112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|x64.Build.0 = Debug|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Debug|x86.Build.0 = Debug|Any CPU
{112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|x64.ActiveCfg = Release|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|x64.Build.0 = Release|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|x86.ActiveCfg = Release|Any CPU
+ {112C5C1D-F0A6-4068-A9EB-6047CA1F5CDF}.Release|x86.Build.0 = Release|Any CPU
{51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|x64.Build.0 = Debug|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Debug|x86.Build.0 = Debug|Any CPU
{51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|Any CPU.Build.0 = Release|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|x64.ActiveCfg = Release|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|x64.Build.0 = Release|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|x86.ActiveCfg = Release|Any CPU
+ {51F052FC-2DCB-48AF-A4D3-5C42C8C5F713}.Release|x86.Build.0 = Release|Any CPU
{A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|x64.Build.0 = Debug|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Debug|x86.Build.0 = Debug|Any CPU
{A350D217-DC32-4537-8A9C-167B560CAF75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A350D217-DC32-4537-8A9C-167B560CAF75}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Release|x64.ActiveCfg = Release|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Release|x64.Build.0 = Release|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Release|x86.ActiveCfg = Release|Any CPU
+ {A350D217-DC32-4537-8A9C-167B560CAF75}.Release|x86.Build.0 = Release|Any CPU
{9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|x64.Build.0 = Debug|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Debug|x86.Build.0 = Debug|Any CPU
{9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|x64.ActiveCfg = Release|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|x64.Build.0 = Release|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|x86.ActiveCfg = Release|Any CPU
+ {9A433C22-4811-4AD9-99C1-3DF85D9FB54B}.Release|x86.Build.0 = Release|Any CPU
{81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|x64.Build.0 = Debug|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Debug|x86.Build.0 = Debug|Any CPU
{81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|Any CPU.Build.0 = Release|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|x64.ActiveCfg = Release|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|x64.Build.0 = Release|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|x86.ActiveCfg = Release|Any CPU
+ {81EA8494-176C-4178-A1C3-6FA3B1222B74}.Release|x86.Build.0 = Release|Any CPU
{085F3A30-A788-48D6-8067-74D71C29A941}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{085F3A30-A788-48D6-8067-74D71C29A941}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Debug|x64.Build.0 = Debug|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Debug|x86.Build.0 = Debug|Any CPU
{085F3A30-A788-48D6-8067-74D71C29A941}.Release|Any CPU.ActiveCfg = Release|Any CPU
{085F3A30-A788-48D6-8067-74D71C29A941}.Release|Any CPU.Build.0 = Release|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Release|x64.ActiveCfg = Release|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Release|x64.Build.0 = Release|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Release|x86.ActiveCfg = Release|Any CPU
+ {085F3A30-A788-48D6-8067-74D71C29A941}.Release|x86.Build.0 = Release|Any CPU
{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|x64.Build.0 = Debug|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Debug|x86.Build.0 = Debug|Any CPU
{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|Any CPU.Build.0 = Release|Any CPU
-
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|x64.ActiveCfg = Release|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|x64.Build.0 = Release|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|x86.ActiveCfg = Release|Any CPU
+ {6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716}.Release|x86.Build.0 = Release|Any CPU
{345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|x64.Build.0 = Debug|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Debug|x86.Build.0 = Debug|Any CPU
{345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|x64.ActiveCfg = Release|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|x64.Build.0 = Release|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|x86.ActiveCfg = Release|Any CPU
+ {345DA0D1-C762-49EF-9953-6F4D57CB7FC7}.Release|x86.Build.0 = Release|Any CPU
{C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|x64.Build.0 = Debug|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Debug|x86.Build.0 = Debug|Any CPU
{C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|x64.ActiveCfg = Release|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|x64.Build.0 = Release|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|x86.ActiveCfg = Release|Any CPU
+ {C95689B5-C0A1-4C1F-9E97-369D3D397930}.Release|x86.Build.0 = Release|Any CPU
{8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|x64.Build.0 = Debug|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Debug|x86.Build.0 = Debug|Any CPU
{8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|x64.ActiveCfg = Release|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|x64.Build.0 = Release|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|x86.ActiveCfg = Release|Any CPU
+ {8551C158-60B4-4594-8B1D-5BE851F90EE4}.Release|x86.Build.0 = Release|Any CPU
{874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|x64.Build.0 = Debug|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Debug|x86.Build.0 = Debug|Any CPU
{874C7405-ED8D-477D-9362-0C69CF56F213}.Release|Any CPU.ActiveCfg = Release|Any CPU
{874C7405-ED8D-477D-9362-0C69CF56F213}.Release|Any CPU.Build.0 = Release|Any CPU
-
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Release|x64.ActiveCfg = Release|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Release|x64.Build.0 = Release|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Release|x86.ActiveCfg = Release|Any CPU
+ {874C7405-ED8D-477D-9362-0C69CF56F213}.Release|x86.Build.0 = Release|Any CPU
{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|x64.Build.0 = Debug|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Debug|x86.Build.0 = Debug|Any CPU
{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|x64.ActiveCfg = Release|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|x64.Build.0 = Release|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|x86.ActiveCfg = Release|Any CPU
+ {05E93A3E-CFA0-4980-8EE5-CD25C7ED766D}.Release|x86.Build.0 = Release|Any CPU
{AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|x64.Build.0 = Debug|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Debug|x86.Build.0 = Debug|Any CPU
{AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|x64.ActiveCfg = Release|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|x64.Build.0 = Release|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|x86.ActiveCfg = Release|Any CPU
+ {AAFC86EB-49D7-4FD8-8C79-C42C129EB75A}.Release|x86.Build.0 = Release|Any CPU
{98A11016-DD41-4848-A848-51D703951A91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98A11016-DD41-4848-A848-51D703951A91}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Debug|x64.Build.0 = Debug|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Debug|x86.Build.0 = Debug|Any CPU
{98A11016-DD41-4848-A848-51D703951A91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98A11016-DD41-4848-A848-51D703951A91}.Release|Any CPU.Build.0 = Release|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Release|x64.ActiveCfg = Release|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Release|x64.Build.0 = Release|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Release|x86.ActiveCfg = Release|Any CPU
+ {98A11016-DD41-4848-A848-51D703951A91}.Release|x86.Build.0 = Release|Any CPU
{106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|x64.Build.0 = Debug|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Debug|x86.Build.0 = Debug|Any CPU
{106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|Any CPU.Build.0 = Release|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|x64.ActiveCfg = Release|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|x64.Build.0 = Release|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|x86.ActiveCfg = Release|Any CPU
+ {106FBE12-6FF7-40DC-9B3C-E5F67F335B32}.Release|x86.Build.0 = Release|Any CPU
{565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|x64.Build.0 = Debug|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Debug|x86.Build.0 = Debug|Any CPU
{565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|Any CPU.ActiveCfg = Release|Any CPU
{565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|Any CPU.Build.0 = Release|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|x64.ActiveCfg = Release|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|x64.Build.0 = Release|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|x86.ActiveCfg = Release|Any CPU
+ {565A9701-3D9C-49F8-86B7-D256A1D9E074}.Release|x86.Build.0 = Release|Any CPU
{EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|x64.Build.0 = Debug|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Debug|x86.Build.0 = Debug|Any CPU
{EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|x64.ActiveCfg = Release|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|x64.Build.0 = Release|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|x86.ActiveCfg = Release|Any CPU
+ {EAF4A3B8-5CD0-48ED-B848-0EA6D451B8D3}.Release|x86.Build.0 = Release|Any CPU
{C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|x64.Build.0 = Debug|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Debug|x86.Build.0 = Debug|Any CPU
{C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|x64.ActiveCfg = Release|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|x64.Build.0 = Release|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|x86.ActiveCfg = Release|Any CPU
+ {C99A0F7C-9477-4985-90F6-8EED38ECAC10}.Release|x86.Build.0 = Release|Any CPU
{D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|x64.Build.0 = Debug|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Debug|x86.Build.0 = Debug|Any CPU
{D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|x64.ActiveCfg = Release|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|x64.Build.0 = Release|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|x86.ActiveCfg = Release|Any CPU
+ {D95519CA-BD27-45AE-B83B-3FB02E7AE445}.Release|x86.Build.0 = Release|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|x64.Build.0 = Debug|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Debug|x86.Build.0 = Debug|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|x64.ActiveCfg = Release|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|x64.Build.0 = Release|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|x86.ActiveCfg = Release|Any CPU
+ {0633CB2B-3508-48E5-A8C2-427A83A5CA6E}.Release|x86.Build.0 = Release|Any CPU
{63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|x64.Build.0 = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Debug|x86.Build.0 = Debug|Any CPU
{63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|Any CPU.Build.0 = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|x64.ActiveCfg = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|x64.Build.0 = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|x86.ActiveCfg = Release|Any CPU
+ {63DC05A0-5B16-45A4-BDE5-90DD2E200507}.Release|x86.Build.0 = Release|Any CPU
{38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|x64.Build.0 = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Debug|x86.Build.0 = Debug|Any CPU
{38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|x64.ActiveCfg = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|x64.Build.0 = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|x86.ActiveCfg = Release|Any CPU
+ {38C8C3B0-163D-4B7B-86A2-3EFFBC165E99}.Release|x86.Build.0 = Release|Any CPU
{1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|x64.Build.0 = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Debug|x86.Build.0 = Debug|Any CPU
{1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|x64.ActiveCfg = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|x64.Build.0 = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|x86.ActiveCfg = Release|Any CPU
+ {1AF980DF-DEEA-4E5D-9001-6EC67EB96AD1}.Release|x86.Build.0 = Release|Any CPU
{3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|x64.Build.0 = Debug|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Debug|x86.Build.0 = Debug|Any CPU
{3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|x64.ActiveCfg = Release|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|x64.Build.0 = Release|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|x86.ActiveCfg = Release|Any CPU
+ {3F159C49-3DE7-42F5-AF14-E64C03AF19E8}.Release|x86.Build.0 = Release|Any CPU
{D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|x64.Build.0 = Debug|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Debug|x86.Build.0 = Debug|Any CPU
{D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|x64.ActiveCfg = Release|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|x64.Build.0 = Release|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|x86.ActiveCfg = Release|Any CPU
+ {D44D50E1-EC65-4A1C-AAA1-C360E4FC563F}.Release|x86.Build.0 = Release|Any CPU
{7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|x64.Build.0 = Debug|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Debug|x86.Build.0 = Debug|Any CPU
{7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|x64.ActiveCfg = Release|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|x64.Build.0 = Release|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|x86.ActiveCfg = Release|Any CPU
+ {7485EAED-F81C-4119-BABC-E009A21ACE46}.Release|x86.Build.0 = Release|Any CPU
{43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|x64.Build.0 = Debug|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Debug|x86.Build.0 = Debug|Any CPU
{43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|Any CPU.Build.0 = Release|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|x64.ActiveCfg = Release|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|x64.Build.0 = Release|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|x86.ActiveCfg = Release|Any CPU
+ {43C5E98B-5EC4-9F2B-2676-8F1E34969855}.Release|x86.Build.0 = Release|Any CPU
{6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|x64.Build.0 = Debug|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Debug|x86.Build.0 = Debug|Any CPU
{6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|x64.ActiveCfg = Release|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|x64.Build.0 = Release|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|x86.ActiveCfg = Release|Any CPU
+ {6B1F00FF-7F1D-C5D8-A8D3-E0EF2886B8C6}.Release|x86.Build.0 = Release|Any CPU
{9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|x64.Build.0 = Debug|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Debug|x86.Build.0 = Debug|Any CPU
{9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|x64.ActiveCfg = Release|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|x64.Build.0 = Release|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|x86.ActiveCfg = Release|Any CPU
+ {9D601495-FDBA-C852-4ACB-EC54EDC9B3E5}.Release|x86.Build.0 = Release|Any CPU
{F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|x64.Build.0 = Debug|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Debug|x86.Build.0 = Debug|Any CPU
{F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|x64.ActiveCfg = Release|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|x64.Build.0 = Release|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|x86.ActiveCfg = Release|Any CPU
+ {F578CA07-E74F-4F47-9203-C67777D9BB78}.Release|x86.Build.0 = Release|Any CPU
{E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|x64.Build.0 = Debug|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Debug|x86.Build.0 = Debug|Any CPU
{E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|x64.ActiveCfg = Release|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|x64.Build.0 = Release|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|x86.ActiveCfg = Release|Any CPU
+ {E10920BB-6409-41BB-9A9D-813BC37CC3C0}.Release|x86.Build.0 = Release|Any CPU
{B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|x64.Build.0 = Debug|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Debug|x86.Build.0 = Debug|Any CPU
{B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|x64.ActiveCfg = Release|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|x64.Build.0 = Release|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|x86.ActiveCfg = Release|Any CPU
+ {B0F91FE2-6AC5-4FA8-B321-54623A516D4D}.Release|x86.Build.0 = Release|Any CPU
{11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|x64.Build.0 = Debug|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Debug|x86.Build.0 = Debug|Any CPU
{11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|Any CPU.Build.0 = Release|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|x64.ActiveCfg = Release|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|x64.Build.0 = Release|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|x86.ActiveCfg = Release|Any CPU
+ {11497EB7-B702-B537-3CBE-BA2F4F85F313}.Release|x86.Build.0 = Release|Any CPU
{2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|x64.Build.0 = Debug|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Debug|x86.Build.0 = Debug|Any CPU
{2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|x64.ActiveCfg = Release|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|x64.Build.0 = Release|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|x86.ActiveCfg = Release|Any CPU
+ {2B6F24A0-4569-E8A2-81B4-3925FA4F0320}.Release|x86.Build.0 = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|x64.Build.0 = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Debug|x86.Build.0 = Debug|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|x64.ActiveCfg = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|x64.Build.0 = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|x86.ActiveCfg = Release|Any CPU
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671}.Release|x86.Build.0 = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|x64.Build.0 = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Debug|x86.Build.0 = Debug|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|x64.ActiveCfg = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|x64.Build.0 = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|x86.ActiveCfg = Release|Any CPU
+ {A30F8E57-AF18-40EC-B130-140585246CC7}.Release|x86.Build.0 = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|x64.Build.0 = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Debug|x86.Build.0 = Debug|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|x64.ActiveCfg = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|x64.Build.0 = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|x86.ActiveCfg = Release|Any CPU
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -378,14 +806,12 @@ Global
{81EA8494-176C-4178-A1C3-6FA3B1222B74} = {39EAAA32-53A8-4641-873C-976FD5963360}
{085F3A30-A788-48D6-8067-74D71C29A941} = {39EAAA32-53A8-4641-873C-976FD5963360}
{6FCC8A6C-A172-4AAF-A0FC-66C3BD9E8716} = {39EAAA32-53A8-4641-873C-976FD5963360}
-
{6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39} = {4429C078-35C8-4E2B-9C7B-F0C619741B67}
{345DA0D1-C762-49EF-9953-6F4D57CB7FC7} = {6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39}
{C95689B5-C0A1-4C1F-9E97-369D3D397930} = {6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39}
{8551C158-60B4-4594-8B1D-5BE851F90EE4} = {6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39}
{874C7405-ED8D-477D-9362-0C69CF56F213} = {6FF2EDB6-D1B8-4EE0-B1F0-2BCE66972E39}
{74979310-8A92-47DC-B5CA-EFA7970E1202} = {4429C078-35C8-4E2B-9C7B-F0C619741B67}
-
{05E93A3E-CFA0-4980-8EE5-CD25C7ED766D} = {D859B39C-9106-4D3D-8C57-11B15FA8106B}
{AAFC86EB-49D7-4FD8-8C79-C42C129EB75A} = {5FBEAD92-9234-4824-9320-2052D236C9CD}
{98A11016-DD41-4848-A848-51D703951A91} = {5FBEAD92-9234-4824-9320-2052D236C9CD}
@@ -414,6 +840,9 @@ Global
{11497EB7-B702-B537-3CBE-BA2F4F85F313} = {F929DB74-DD0E-B0EF-AA66-D8703D547BBD}
{A65C33EA-4F2E-DE85-7501-4389A2100813} = {F929DB74-DD0E-B0EF-AA66-D8703D547BBD}
{2B6F24A0-4569-E8A2-81B4-3925FA4F0320} = {A65C33EA-4F2E-DE85-7501-4389A2100813}
+ {4E74F2DB-3BA5-4390-8FBF-C58F57601671} = {BC1690DE-FD9E-72EA-CAED-A2B9A3D6B335}
+ {A30F8E57-AF18-40EC-B130-140585246CC7} = {BC1690DE-FD9E-72EA-CAED-A2B9A3D6B335}
+ {1DB37AC5-18FE-4535-816C-827B4D3DCB96} = {BC1690DE-FD9E-72EA-CAED-A2B9A3D6B335}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {08502818-E8E1-4A91-A51C-4C8C8D4FF9CA}
diff --git a/dotnetv4/Redshift/Actions/HelloRedshift.cs b/dotnetv4/Redshift/Actions/HelloRedshift.cs
new file mode 100644
index 00000000000..2527f82d68b
--- /dev/null
+++ b/dotnetv4/Redshift/Actions/HelloRedshift.cs
@@ -0,0 +1,61 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+using Amazon.Redshift.Model;
+using Microsoft.Extensions.Logging;
+
+namespace RedshiftActions;
+
+///
+/// Hello Amazon Redshift example.
+///
+public class HelloRedshift
+{
+ private static ILogger logger = null!;
+
+ // snippet-start:[Redshift.dotnetv4.Hello]
+ ///
+ /// Main method to run the Hello Amazon Redshift example.
+ ///
+ /// Command line arguments (not used).
+ public static async Task Main(string[] args)
+ {
+ var redshiftClient = new AmazonRedshiftClient();
+
+ Console.WriteLine("Hello, Amazon Redshift! Let's list available clusters:");
+
+ var clusters = new List();
+
+ try
+ {
+ // Use pagination to retrieve all clusters.
+ var clustersPaginator = redshiftClient.Paginators.DescribeClusters(new DescribeClustersRequest());
+
+ await foreach (var response in clustersPaginator.Responses)
+ {
+ if (response.Clusters != null)
+ clusters.AddRange(response.Clusters);
+ }
+
+ Console.WriteLine($"{clusters.Count} cluster(s) retrieved.");
+
+ foreach (var cluster in clusters)
+ {
+ Console.WriteLine($"\t{cluster.ClusterIdentifier} (Status: {cluster.ClusterStatus})");
+ }
+ }
+ catch (AmazonRedshiftException ex)
+ {
+ Console.WriteLine($"Couldn't list clusters. Here's why: {ex.Message}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"An error occurred: {ex.Message}");
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.Hello]
+}
\ No newline at end of file
diff --git a/dotnetv4/Redshift/Actions/RedshiftActions.csproj b/dotnetv4/Redshift/Actions/RedshiftActions.csproj
new file mode 100644
index 00000000000..899ba4b8047
--- /dev/null
+++ b/dotnetv4/Redshift/Actions/RedshiftActions.csproj
@@ -0,0 +1,28 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ latest
+ RedshiftActions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
diff --git a/dotnetv4/Redshift/Actions/RedshiftWrapper.cs b/dotnetv4/Redshift/Actions/RedshiftWrapper.cs
new file mode 100644
index 00000000000..acab6f29170
--- /dev/null
+++ b/dotnetv4/Redshift/Actions/RedshiftWrapper.cs
@@ -0,0 +1,505 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+using Amazon.Redshift.Model;
+using Amazon.RedshiftDataAPIService;
+using Amazon.RedshiftDataAPIService.Model;
+
+namespace RedshiftActions;
+
+// snippet-start:[Redshift.dotnetv4.RedshiftWrapper]
+///
+/// Wrapper class for Amazon Redshift operations.
+///
+public class RedshiftWrapper
+{
+ private readonly IAmazonRedshift _redshiftClient;
+ private readonly IAmazonRedshiftDataAPIService _redshiftDataClient;
+
+ ///
+ /// Constructor for RedshiftWrapper.
+ ///
+ /// Amazon Redshift client.
+ /// Amazon Redshift Data API client.
+ public RedshiftWrapper(IAmazonRedshift redshiftClient, IAmazonRedshiftDataAPIService redshiftDataClient)
+ {
+ _redshiftClient = redshiftClient;
+ _redshiftDataClient = redshiftDataClient;
+ }
+
+ // snippet-start:[Redshift.dotnetv4.CreateCluster]
+ ///
+ /// Create a new Amazon Redshift cluster.
+ ///
+ /// The identifier for the cluster.
+ /// The name of the database.
+ /// The master username.
+ /// The master user password.
+ /// The node type for the cluster.
+ /// The cluster that was created.
+ public async Task CreateClusterAsync(string clusterIdentifier, string databaseName,
+ string masterUsername, string masterUserPassword, string nodeType = "ra3.large")
+ {
+ try
+ {
+ var request = new CreateClusterRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ DBName = databaseName,
+ MasterUsername = masterUsername,
+ MasterUserPassword = masterUserPassword,
+ NodeType = nodeType,
+ NumberOfNodes = 1,
+ ClusterType = "single-node"
+ };
+
+ var response = await _redshiftClient.CreateClusterAsync(request);
+ Console.WriteLine($"Created cluster {clusterIdentifier}");
+ return response.Cluster;
+ }
+ catch (ClusterAlreadyExistsException ex)
+ {
+ Console.WriteLine($"Cluster already exists: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't create cluster. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.CreateCluster]
+
+ // snippet-start:[Redshift.dotnetv4.DescribeClusters]
+ ///
+ /// Describe Amazon Redshift clusters.
+ ///
+ /// Optional cluster identifier to describe a specific cluster.
+ /// A list of clusters.
+ public async Task> DescribeClustersAsync(string? clusterIdentifier = null)
+ {
+ try
+ {
+ var clusters = new List();
+ var request = new DescribeClustersRequest();
+ if (!string.IsNullOrEmpty(clusterIdentifier))
+ {
+ request.ClusterIdentifier = clusterIdentifier;
+ }
+
+ var clustersPaginator = _redshiftClient.Paginators.DescribeClusters(request);
+ await foreach (var response in clustersPaginator.Responses)
+ {
+ if (response.Clusters != null)
+ clusters.AddRange(response.Clusters);
+ }
+
+ Console.WriteLine($"{clusters.Count} cluster(s) retrieved.");
+ foreach (var cluster in clusters)
+ {
+ Console.WriteLine($"\t{cluster.ClusterIdentifier} (Status: {cluster.ClusterStatus})");
+ }
+
+ return clusters;
+ }
+ catch (ClusterNotFoundException ex)
+ {
+ Console.WriteLine($"Cluster {clusterIdentifier} not found: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't describe clusters. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.DescribeClusters]
+
+ // snippet-start:[Redshift.dotnetv4.ModifyCluster]
+ ///
+ /// Modify an Amazon Redshift cluster.
+ ///
+ /// The identifier for the cluster.
+ /// The preferred maintenance window.
+ /// True if successful.
+ public async Task ModifyClusterAsync(string clusterIdentifier, string preferredMaintenanceWindow)
+ {
+ try
+ {
+ var request = new ModifyClusterRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ PreferredMaintenanceWindow = preferredMaintenanceWindow
+ };
+
+ var response = await _redshiftClient.ModifyClusterAsync(request);
+ Console.WriteLine($"The modified cluster was successfully modified and has {response.Cluster.PreferredMaintenanceWindow} as the maintenance window");
+ return true;
+ }
+ catch (ClusterNotFoundException ex)
+ {
+ Console.WriteLine($"Cluster {clusterIdentifier} not found: {ex.Message}");
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't modify cluster. Here's why: {ex.Message}");
+ return false;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.ModifyCluster]
+
+ // snippet-start:[Redshift.dotnetv4.DeleteCluster]
+ ///
+ /// Delete an Amazon Redshift cluster without a final snapshot.
+ ///
+ /// The identifier for the cluster.
+ /// True if successful.
+ public async Task DeleteClusterWithoutSnapshotAsync(string clusterIdentifier)
+ {
+ try
+ {
+ var request = new DeleteClusterRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ SkipFinalClusterSnapshot = true
+ };
+
+ var response = await _redshiftClient.DeleteClusterAsync(request);
+ Console.WriteLine($"The {clusterIdentifier} was deleted");
+ return true;
+ }
+ catch (ClusterNotFoundException ex)
+ {
+ Console.WriteLine($"Cluster not found: {ex.Message}");
+ return false;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't delete cluster. Here's why: {ex.Message}");
+ return false;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.DeleteCluster]
+
+ // snippet-start:[Redshift.dotnetv4.ListDatabases]
+ ///
+ /// List databases in a Redshift cluster.
+ ///
+ /// The cluster identifier.
+ /// The database user.
+ /// The database name for authentication.
+ /// A list of database names.
+ public async Task> ListDatabasesAsync(string clusterIdentifier, string dbUser, string databaseName)
+ {
+ try
+ {
+ var request = new ListDatabasesRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ DbUser = dbUser,
+ Database = databaseName
+ };
+
+ var response = await _redshiftDataClient.ListDatabasesAsync(request);
+ var databases = new List();
+
+ foreach (var database in response.Databases)
+ {
+ Console.WriteLine($"The database name is : {database}");
+ databases.Add(database);
+ }
+
+ return databases;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ValidationException ex)
+ {
+ Console.WriteLine($"Validation error: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't list databases. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.ListDatabases]
+
+ // snippet-start:[Redshift.dotnetv4.CreateTable]
+ ///
+ /// Create a table in the Redshift database.
+ ///
+ /// The cluster identifier.
+ /// The database name.
+ /// The database user.
+ /// The statement ID.
+ public async Task CreateTableAsync(string clusterIdentifier, string database, string dbUser)
+ {
+ try
+ {
+ var sqlStatement = @"
+ CREATE TABLE Movies (
+ id INTEGER PRIMARY KEY,
+ title VARCHAR(250) NOT NULL,
+ year INTEGER NOT NULL
+ )";
+
+ var request = new ExecuteStatementRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ Database = database,
+ DbUser = dbUser,
+ Sql = sqlStatement
+ };
+
+ var response = await _redshiftDataClient.ExecuteStatementAsync(request);
+ await WaitForStatementToCompleteAsync(response.Id);
+ Console.WriteLine("Table created: Movies");
+ return response.Id;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ValidationException ex)
+ {
+ Console.WriteLine($"Validation error: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't create table. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.CreateTable]
+
+ // snippet-start:[Redshift.dotnetv4.Insert]
+ ///
+ /// Insert a record into the Movies table using parameterized query.
+ ///
+ /// The cluster identifier.
+ /// The database name.
+ /// The database user.
+ /// The movie ID.
+ /// The movie title.
+ /// The movie year.
+ /// The statement ID.
+ public async Task InsertMovieAsync(string clusterIdentifier, string database, string dbUser,
+ int id, string title, int year)
+ {
+ try
+ {
+ var sqlStatement = "INSERT INTO Movies (id, title, year) VALUES (:id, :title, :year)";
+
+ var request = new ExecuteStatementRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ Database = database,
+ DbUser = dbUser,
+ Sql = sqlStatement,
+ Parameters = new List
+ {
+ new SqlParameter { Name = "id", Value = id.ToString() },
+ new SqlParameter { Name = "title", Value = title },
+ new SqlParameter { Name = "year", Value = year.ToString() }
+ }
+ };
+
+ var response = await _redshiftDataClient.ExecuteStatementAsync(request);
+ await WaitForStatementToCompleteAsync(response.Id);
+ Console.WriteLine($"Inserted: {title} ({year})");
+ return response.Id;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ValidationException ex)
+ {
+ Console.WriteLine($"Validation error: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't insert movie. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.Insert]
+
+ // snippet-start:[Redshift.dotnetv4.Query]
+ ///
+ /// Query movies by year using parameterized query.
+ ///
+ /// The cluster identifier.
+ /// The database name.
+ /// The database user.
+ /// The year to query.
+ /// A list of movie titles.
+ public async Task> QueryMoviesByYearAsync(string clusterIdentifier, string database,
+ string dbUser, int year)
+ {
+ try
+ {
+ var sqlStatement = "SELECT title FROM Movies WHERE year = :year";
+
+ var request = new ExecuteStatementRequest
+ {
+ ClusterIdentifier = clusterIdentifier,
+ Database = database,
+ DbUser = dbUser,
+ Sql = sqlStatement,
+ Parameters = new List
+ {
+ new SqlParameter { Name = "year", Value = year.ToString() }
+ }
+ };
+
+ var response = await _redshiftDataClient.ExecuteStatementAsync(request);
+ Console.WriteLine($"The identifier of the statement is {response.Id}");
+
+ await WaitForStatementToCompleteAsync(response.Id);
+
+ var results = await GetStatementResultAsync(response.Id);
+ var movieTitles = new List();
+
+ foreach (var row in results)
+ {
+ if (row.Count > 0)
+ {
+ var title = row[0].StringValue;
+ Console.WriteLine($"The Movie title field is {title}");
+ movieTitles.Add(title);
+ }
+ }
+
+ return movieTitles;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ValidationException ex)
+ {
+ Console.WriteLine($"Validation error: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't query movies. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.Query]
+
+ // snippet-start:[Redshift.dotnetv4.DescribeStatement]
+ ///
+ /// Describe a statement execution.
+ ///
+ /// The statement ID.
+ /// The statement description.
+ public async Task DescribeStatementAsync(string statementId)
+ {
+ try
+ {
+ var request = new DescribeStatementRequest
+ {
+ Id = statementId
+ };
+
+ var response = await _redshiftDataClient.DescribeStatementAsync(request);
+ return response;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ResourceNotFoundException ex)
+ {
+ Console.WriteLine($"Statement not found: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't describe statement. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.DescribeStatement]
+
+ // snippet-start:[Redshift.dotnetv4.GetStatementResult]
+ ///
+ /// Get the results of a statement execution.
+ ///
+ /// The statement ID.
+ /// A list of result rows.
+ public async Task>> GetStatementResultAsync(string statementId)
+ {
+ try
+ {
+ var request = new GetStatementResultRequest
+ {
+ Id = statementId
+ };
+
+ var response = await _redshiftDataClient.GetStatementResultAsync(request);
+ return response.Records;
+ }
+ catch (Amazon.RedshiftDataAPIService.Model.ResourceNotFoundException ex)
+ {
+ Console.WriteLine($"Statement not found: {ex.Message}");
+ throw;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Couldn't get statement result. Here's why: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[Redshift.dotnetv4.GetStatementResult]
+
+ ///
+ /// Wait for a statement to complete execution.
+ ///
+ /// The statement ID.
+ /// A task representing the asynchronous operation.
+ private async Task WaitForStatementToCompleteAsync(string statementId)
+ {
+ var status = StatusString.SUBMITTED;
+ DescribeStatementResponse? response = null;
+
+ while (status == StatusString.SUBMITTED || status == StatusString.PICKED || status == StatusString.STARTED)
+ {
+ await Task.Delay(1000); // Wait 1 second
+ response = await DescribeStatementAsync(statementId);
+ status = response.Status;
+ Console.WriteLine($"...{status}");
+ }
+
+ if (status == StatusString.FINISHED)
+ {
+ Console.WriteLine("The statement is finished!");
+ }
+ else
+ {
+ var errorMessage = response?.Error ?? "Unknown error";
+ Console.WriteLine($"The statement failed with status: {status}");
+ Console.WriteLine($"Error message: {errorMessage}");
+ }
+ }
+
+ ///
+ /// Wait for a cluster to become available.
+ ///
+ /// The cluster identifier.
+ /// A task representing the asynchronous operation.
+ public async Task WaitForClusterAvailableAsync(string clusterIdentifier)
+ {
+ Console.WriteLine($"Wait until {clusterIdentifier} is available. This may take a few minutes.");
+
+ var startTime = DateTime.Now;
+ var clusters = await DescribeClustersAsync(clusterIdentifier);
+
+ while (clusters[0].ClusterStatus != "available")
+ {
+ var elapsed = DateTime.Now - startTime;
+ Console.WriteLine($"Elapsed Time: {elapsed:mm\\:ss} - Waiting for cluster...");
+
+ await Task.Delay(5000); // Wait 5 seconds
+ clusters = await DescribeClustersAsync(clusterIdentifier);
+ }
+
+ var totalElapsed = DateTime.Now - startTime;
+ Console.WriteLine($"Cluster is available! Total Elapsed Time: {totalElapsed:mm\\:ss}");
+ }
+}
+// snippet-end:[Redshift.dotnetv4.RedshiftWrapper]
\ No newline at end of file
diff --git a/dotnetv4/Redshift/README.md b/dotnetv4/Redshift/README.md
new file mode 100644
index 00000000000..6965d9bd97f
--- /dev/null
+++ b/dotnetv4/Redshift/README.md
@@ -0,0 +1,119 @@
+# Amazon Redshift code examples for the SDK for .NET (v4)
+
+## Overview
+
+Shows how to use the AWS SDK for .NET (v4) to work with Amazon Redshift.
+
+
+
+
+_Amazon Redshift is a fast, fully managed, petabyte-scale data warehouse service that makes it simple and cost-effective to efficiently analyze all your data using your existing business intelligence tools._
+
+## ⚠ Important
+
+* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/).
+* Running the tests might result in charges to your AWS account.
+* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
+* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).
+
+
+
+
+## Code examples
+
+### Prerequisites
+
+For prerequisites, see the [README](../README.md#Prerequisites) in the `dotnetv4` folder.
+
+
+
+
+
+### Get started
+
+- [Hello Amazon Redshift](Actions/HelloRedshift.cs#L20) (`DescribeClusters`)
+
+
+### Basics
+
+Code examples that show you how to perform the essential operations within a service.
+
+- [Learn the basics](Actions/RedshiftWrapper.cs)
+
+
+### Single actions
+
+Code excerpts that show you how to call individual service functions.
+
+- [CreateCluster](Actions/RedshiftWrapper.cs#L34)
+- [DeleteCluster](Actions/RedshiftWrapper.cs#L156)
+- [DescribeClusters](Actions/RedshiftWrapper.cs#L77)
+- [DescribeStatement](Actions/RedshiftWrapper.cs#L388)
+- [GetStatementResult](Actions/RedshiftWrapper.cs#L419)
+- [ListDatabases](Actions/RedshiftWrapper.cs#L189)
+- [ModifyCluster](Actions/RedshiftWrapper.cs#L122)
+
+
+
+
+
+## Run the examples
+
+### Instructions
+
+
+
+
+
+#### Hello Amazon Redshift
+
+This example shows you how to get started using Amazon Redshift.
+
+
+#### Learn the basics
+
+This example shows you how to do the following:
+
+- Create a Redshift cluster.
+- List databases in the cluster.
+- Create a table named Movies.
+- Populate the Movies table.
+- Query the Movies table by year.
+- Modify the Redshift cluster.
+- Delete the Amazon Redshift cluster.
+
+
+
+
+
+
+
+
+
+### Tests
+
+⚠ Running tests might result in charges to your AWS account.
+
+
+To find instructions for running these tests, see the [README](../README.md#Tests)
+in the `dotnetv4` folder.
+
+
+
+
+
+
+## Additional resources
+
+- [Amazon Redshift Management Guide](https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html)
+- [Amazon Redshift API Reference](https://docs.aws.amazon.com/redshift/latest/APIReference/Welcome.html)
+- [SDK for .NET (v4) Amazon Redshift reference](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Redshift/NRedshift.html)
+
+
+
+
+---
+
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
diff --git a/dotnetv4/Redshift/RedshiftExamples.sln b/dotnetv4/Redshift/RedshiftExamples.sln
new file mode 100644
index 00000000000..ca60478e539
--- /dev/null
+++ b/dotnetv4/Redshift/RedshiftExamples.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33414.496
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedshiftActions", "Actions\RedshiftActions.csproj", "{A1B2C3D4-E5F6-4A5B-8C9D-1E2F3A4B5C6D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedshiftBasics", "Scenarios\RedshiftBasics.csproj", "{C3D4E5F6-A7B8-4C5D-9E1F-3A4B5C6D7E8F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedshiftTests", "Tests\RedshiftTests.csproj", "{D4E5F6A7-B8C9-4D5E-9F1A-4B5C6D7E8F9A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A1B2C3D4-E5F6-4A5B-8C9D-1E2F3A4B5C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A1B2C3D4-E5F6-4A5B-8C9D-1E2F3A4B5C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A1B2C3D4-E5F6-4A5B-8C9D-1E2F3A4B5C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A1B2C3D4-E5F6-4A5B-8C9D-1E2F3A4B5C6D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C3D4E5F6-A7B8-4C5D-9E1F-3A4B5C6D7E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C3D4E5F6-A7B8-4C5D-9E1F-3A4B5C6D7E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C3D4E5F6-A7B8-4C5D-9E1F-3A4B5C6D7E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C3D4E5F6-A7B8-4C5D-9E1F-3A4B5C6D7E8F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4E5F6A7-B8C9-4D5E-9F1A-4B5C6D7E8F9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D4E5F6A7-B8C9-4D5E-9F1A-4B5C6D7E8F9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4E5F6A7-B8C9-4D5E-9F1A-4B5C6D7E8F9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D4E5F6A7-B8C9-4D5E-9F1A-4B5C6D7E8F9A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F1A2B3C4-D5E6-4F7A-8B9C-0D1E2F3A4B5C}
+ EndGlobalSection
+EndGlobal
diff --git a/dotnetv4/Redshift/Scenarios/RedshiftBasics.cs b/dotnetv4/Redshift/Scenarios/RedshiftBasics.cs
new file mode 100644
index 00000000000..6adab87011f
--- /dev/null
+++ b/dotnetv4/Redshift/Scenarios/RedshiftBasics.cs
@@ -0,0 +1,283 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+using Amazon.RedshiftDataAPIService;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using RedshiftActions;
+
+namespace RedshiftBasics;
+
+// snippet-start:[Redshift.dotnetv4.RedshiftScenario]
+///
+/// Amazon Redshift Getting Started Scenario.
+///
+public class RedshiftBasics
+{
+ public static bool IsInteractive = true;
+ public static RedshiftWrapper? Wrapper = null;
+ public static ILogger logger = null!;
+ private static readonly string _moviesFilePath = "../../../../../../resources/sample_files/movies.json";
+
+ ///
+ /// Main method for the Amazon Redshift Getting Started scenario.
+ ///
+ /// Command line arguments.
+ public static async Task Main(string[] args)
+ {
+ using var host = Host.CreateDefaultBuilder(args)
+ .ConfigureServices((_, services) =>
+ services.AddAWSService()
+ .AddAWSService()
+ .AddTransient()
+ )
+ .Build();
+
+ logger = LoggerFactory.Create(builder => { builder.AddConsole(); })
+ .CreateLogger();
+
+ Wrapper = host.Services.GetRequiredService();
+
+ await RunScenarioAsync();
+ }
+
+ ///
+ /// Run the complete Amazon Redshift scenario.
+ ///
+ public static async Task RunScenarioAsync()
+ {
+ // Set all variables to default values
+ string userName = "awsuser";
+ string userPassword = "AwsUser1000";
+ string clusterIdentifier = "redshift-cluster-movies";
+ var databaseName = "dev";
+ int recordCount = 50;
+ int year = 2013;
+ try
+ {
+ Console.WriteLine(
+ "================================================================================");
+ Console.WriteLine("Welcome to the Amazon Redshift SDK Getting Started scenario.");
+ Console.WriteLine(
+ "This .NET program demonstrates how to interact with Amazon Redshift by using the AWS SDK for .NET.");
+ Console.WriteLine("Let's get started...");
+ Console.WriteLine(
+ "================================================================================");
+
+ // Step 1: Get user credentials (if interactive)
+ if (IsInteractive)
+ {
+ Console.WriteLine("Please enter a user name for the cluster (default is awsuser):");
+ var userInput = Console.ReadLine();
+ if (!string.IsNullOrEmpty(userInput))
+ userName = userInput;
+
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("Please enter a user password for the cluster (default is AwsUser1000):");
+ var passwordInput = Console.ReadLine();
+ if (!string.IsNullOrEmpty(passwordInput))
+ userPassword = passwordInput;
+
+ Console.WriteLine("================================================================================");
+
+ // Step 2: Get cluster identifier
+ Console.WriteLine("Enter a cluster id value (default is redshift-cluster-movies):");
+ var clusterInput = Console.ReadLine();
+ if (!string.IsNullOrEmpty(clusterInput))
+ clusterIdentifier = clusterInput;
+ }
+ else
+ {
+ Console.WriteLine($"Using default values: userName={userName}, clusterIdentifier={clusterIdentifier}");
+ }
+
+ // Step 3: Create Redshift cluster
+ await Wrapper!.CreateClusterAsync(clusterIdentifier, databaseName, userName, userPassword);
+ Console.WriteLine("================================================================================");
+
+ // Step 4: Wait for cluster to become available
+ Console.WriteLine("================================================================================");
+ await Wrapper.WaitForClusterAvailableAsync(clusterIdentifier);
+ Console.WriteLine("================================================================================");
+
+ // Step 5: List databases
+ Console.WriteLine("================================================================================");
+ Console.WriteLine($" When you created {clusterIdentifier}, the dev database is created by default and used in this scenario.");
+ Console.WriteLine(" To create a custom database, you need to have a CREATEDB privilege.");
+ Console.WriteLine(" For more information, see the documentation here: https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_DATABASE.html.");
+ if (IsInteractive)
+ {
+ Console.WriteLine("Press Enter to continue...");
+ Console.ReadLine();
+ }
+ Console.WriteLine("================================================================================");
+
+ Console.WriteLine("================================================================================");
+ Console.WriteLine($"List databases in {clusterIdentifier}");
+ if (IsInteractive)
+ {
+ Console.WriteLine("Press Enter to continue...");
+ Console.ReadLine();
+ }
+ await Wrapper.ListDatabasesAsync(clusterIdentifier, userName, databaseName);
+ Console.WriteLine("================================================================================");
+
+ // Step 6: Create Movies table
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("Now you will create a table named Movies.");
+ if (IsInteractive)
+ {
+ Console.WriteLine("Press Enter to continue...");
+ Console.ReadLine();
+ }
+ await Wrapper.CreateTableAsync(clusterIdentifier, databaseName, userName);
+ Console.WriteLine("================================================================================");
+
+ // Step 7: Populate the Movies table
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("Populate the Movies table using the Movies.json file.");
+
+ if (IsInteractive)
+ {
+ Console.WriteLine("Specify the number of records you would like to add to the Movies Table.");
+ Console.WriteLine("Please enter a value between 50 and 200.");
+ Console.Write("Enter a value: ");
+
+ var recordCountInput = Console.ReadLine();
+ if (int.TryParse(recordCountInput, out var inputCount) && inputCount is >= 50 and <= 200)
+ {
+ recordCount = inputCount;
+ }
+ else
+ {
+ Console.WriteLine($"Invalid input. Using default value of {recordCount}.");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"Using default record count: {recordCount}");
+ }
+
+ await PopulateMoviesTableAsync(clusterIdentifier, databaseName, userName, recordCount);
+ Console.WriteLine($"{recordCount} records were added to the Movies table.");
+ Console.WriteLine("================================================================================");
+
+ // Step 8 & 9: Query movies by year
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("Query the Movies table by year. Enter a value between 2012-2014.");
+
+ if (IsInteractive)
+ {
+ Console.Write("Enter a year: ");
+ var yearInput = Console.ReadLine();
+ if (int.TryParse(yearInput, out var inputYear) && inputYear is >= 2012 and <= 2014)
+ {
+ year = inputYear;
+ }
+ else
+ {
+ Console.WriteLine($"Invalid input. Using default value of {year}.");
+ }
+ }
+ else
+ {
+ Console.WriteLine($"Using default year: {year}");
+ }
+
+ await Wrapper.QueryMoviesByYearAsync(clusterIdentifier, databaseName, userName, year);
+ Console.WriteLine("================================================================================");
+
+ // Step 10: Modify the cluster
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("Now you will modify the Redshift cluster.");
+ if (IsInteractive)
+ {
+ Console.WriteLine("Press Enter to continue...");
+ Console.ReadLine();
+ }
+ await Wrapper.ModifyClusterAsync(clusterIdentifier, "wed:07:30-wed:08:00");
+ Console.WriteLine("================================================================================");
+
+ // Step 11 & 12: Delete cluster confirmation
+ Console.WriteLine("================================================================================");
+ if (IsInteractive)
+ {
+ Console.WriteLine("Would you like to delete the Amazon Redshift cluster? (y/n)");
+ var deleteResponse = Console.ReadLine();
+ if (deleteResponse?.ToLower() == "y")
+ {
+ await Wrapper.DeleteClusterWithoutSnapshotAsync(clusterIdentifier);
+ }
+ }
+ else
+ {
+ Console.WriteLine("Deleting the Amazon Redshift cluster...");
+ await Wrapper.DeleteClusterWithoutSnapshotAsync(clusterIdentifier);
+ }
+ Console.WriteLine("================================================================================");
+
+ Console.WriteLine("================================================================================");
+ Console.WriteLine("This concludes the Amazon Redshift SDK Getting Started scenario.");
+ Console.WriteLine("================================================================================");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"An error occurred during the scenario: {ex.Message}");
+ Console.WriteLine("Deleting the Amazon Redshift cluster...");
+ await Wrapper!.DeleteClusterWithoutSnapshotAsync(clusterIdentifier);
+ throw;
+ }
+ }
+
+ ///
+ /// Populate the Movies table with data from the JSON file.
+ ///
+ /// The cluster identifier.
+ /// The database name.
+ /// The database user.
+ /// Number of records to insert.
+ private static async Task PopulateMoviesTableAsync(string clusterIdentifier, string database, string dbUser, int recordCount)
+ {
+ if (!File.Exists(_moviesFilePath))
+ {
+ throw new FileNotFoundException($"Required movies data file not found at: {_moviesFilePath}");
+ }
+
+ var jsonContent = await File.ReadAllTextAsync(_moviesFilePath);
+ var options = new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ };
+ var movies = JsonSerializer.Deserialize>(jsonContent, options);
+
+ if (movies == null || movies.Count == 0)
+ {
+ throw new InvalidOperationException("Failed to parse movies JSON file or file is empty.");
+ }
+
+ var insertCount = Math.Min(recordCount, movies.Count);
+
+ for (int i = 0; i < insertCount; i++)
+ {
+ var movie = movies[i];
+ await Wrapper!.InsertMovieAsync(clusterIdentifier, database, dbUser, i, movie.Title, movie.Year);
+ }
+ }
+
+ ///
+ /// Movie data model.
+ ///
+ private class Movie
+ {
+ public string Title { get; set; } = string.Empty;
+ public int Year { get; set; }
+ }
+}
+// snippet-end:[Redshift.dotnetv4.RedshiftScenario]
\ No newline at end of file
diff --git a/dotnetv4/Redshift/Scenarios/RedshiftBasics.csproj b/dotnetv4/Redshift/Scenarios/RedshiftBasics.csproj
new file mode 100644
index 00000000000..df3ebce01f5
--- /dev/null
+++ b/dotnetv4/Redshift/Scenarios/RedshiftBasics.csproj
@@ -0,0 +1,29 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ latest
+ RedshiftBasics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
diff --git a/dotnetv4/Redshift/Tests/RedshiftIntegrationTests.cs b/dotnetv4/Redshift/Tests/RedshiftIntegrationTests.cs
new file mode 100644
index 00000000000..89eb84f403c
--- /dev/null
+++ b/dotnetv4/Redshift/Tests/RedshiftIntegrationTests.cs
@@ -0,0 +1,61 @@
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+using Amazon.RedshiftDataAPIService;
+using Microsoft.Extensions.Logging;
+using Moq;
+using RedshiftActions;
+using Xunit;
+
+namespace RedshiftTests;
+
+///
+/// Integration tests for the AWS Redshift Basics scenario.
+///
+public class RedshiftBasicsTests
+{
+ ///
+ /// Verifies the scenario with an integration test. No errors should be logged.
+ ///
+ /// Async task.
+ [Fact]
+ [Trait("Category", "Integration")]
+ public async Task TestScenarioIntegration()
+ {
+ // Arrange
+ RedshiftBasics.RedshiftBasics.IsInteractive = false;
+
+ var loggerScenarioMock = new Mock>();
+
+ loggerScenarioMock.Setup(logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Error),
+ It.IsAny(),
+ It.Is((@object, @type) => true),
+ It.IsAny(),
+ It.IsAny>()
+ ));
+
+ // Act
+ RedshiftBasics.RedshiftBasics.logger = loggerScenarioMock.Object;
+
+ // Act
+ RedshiftBasics.RedshiftBasics.Wrapper = new RedshiftWrapper(
+ new AmazonRedshiftClient(),
+ new AmazonRedshiftDataAPIServiceClient());
+
+ await RedshiftBasics.RedshiftBasics.RunScenarioAsync();
+
+ // Assert no errors logged
+ loggerScenarioMock.Verify(
+ logger => logger.Log(
+ It.Is(logLevel => logLevel == LogLevel.Error),
+ It.IsAny(),
+ It.Is((@object, @type) => true),
+ It.IsAny(),
+ It.IsAny>()),
+ Times.Never);
+ }
+}
\ No newline at end of file
diff --git a/dotnetv4/Redshift/Tests/RedshiftTests.csproj b/dotnetv4/Redshift/Tests/RedshiftTests.csproj
new file mode 100644
index 00000000000..edcc870eb3b
--- /dev/null
+++ b/dotnetv4/Redshift/Tests/RedshiftTests.csproj
@@ -0,0 +1,38 @@
+
+
+
+ net8.0
+ false
+ enable
+ latest
+ RedshiftTests
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
diff --git a/scenarios/basics/redshift/SPECIFICATION.md b/scenarios/basics/redshift/SPECIFICATION.md
index b518011e2e8..086326c8efe 100644
--- a/scenarios/basics/redshift/SPECIFICATION.md
+++ b/scenarios/basics/redshift/SPECIFICATION.md
@@ -13,6 +13,20 @@ The following user input is required for this SDK getting started scenario:
- The year to use to query records from the database.
- Whether or not to delete the Amazon Redshift cluster.
+## SQL Statement Requirements
+
+All SQL statements that include user input or variable data MUST use parameterized queries to prevent SQL injection vulnerabilities. This applies to:
+
+- INSERT statements when adding movie records (use parameters for id, title, and year values)
+- SELECT statements when querying by year (use parameters for the year value)
+- Any other SQL operations that incorporate dynamic values
+
+Example of parameterized query usage:
+- Instead of: `SELECT * FROM Movies WHERE year = 2013`
+- Use: `SELECT * FROM Movies WHERE year = :year` with a parameter binding for `:year`
+
+This security best practice ensures that user input is properly escaped and prevents malicious SQL code injection.
+
## Hello Redshift
This program is intended for users not familiar with the Redshift SDK to easily get up an running. The logic is to show use of `redshiftClient.describeClustersPaginator()`.
@@ -148,6 +162,21 @@ This concludes the Amazon Redshift SDK Getting Started scenario.
```
+## Exception Handling
+
+The following table lists the exceptions that should be caught and handled for each action in the scenario:
+
+| Action | Exception | Handling |
+|---------------------------|--------------------------------|---------------------------------------------------------------------------------------------|
+| `createCluster` | ClusterAlreadyExistsFault | Notify the user that a cluster with this identifier already exists and exit. |
+| `describeClusters` | ClusterNotFoundFault | Notify the user that the specified cluster was not found. |
+| `listDatabases` | ValidationException | Notify the user that the cluster is not available or parameters are invalid. |
+| `executeStatement` | ValidationException | Notify the user of SQL syntax errors or invalid query parameters. |
+| `describeStatement` | ResourceNotFoundException | Notify the user that the statement ID was not found. |
+| `getStatementResult` | ResourceNotFoundException | Notify the user that results are not available for the statement ID. |
+| `modifyCluster` | ClusterNotFoundFault | Notify the user that the cluster to modify was not found. |
+| `deleteCluster` | ClusterNotFoundFault | Notify the user that the cluster to delete was not found. |
+
## SOS Tags
The following table describes the metadata used in this SDK Getting Started Scenario.
diff --git a/steering_docs/dotnet-tech.md b/steering_docs/dotnet-tech.md
index 290814eaf05..4b6b8aca1f7 100644
--- a/steering_docs/dotnet-tech.md
+++ b/steering_docs/dotnet-tech.md
@@ -45,12 +45,16 @@ dotnet format # Format code
- **Documentation**: Include XML documentation explaining the hello example purpose
#### Code Structure Standards
-- **Namespace naming**: Use reverse domain notation (e.g., `Amazon.DocSamples.S3`)
+- **Namespace naming**: Use file-scoped namespaces (e.g., `namespace RedshiftActions;`)
- **Class structure**: One public class per file matching filename
- **Method naming**: Use PascalCase for method names
- **Properties**: Use PascalCase for property names
- **Constants**: Use PascalCase for constants
- **Async methods**: Suffix with `Async` (e.g., `ListBucketsAsync`)
+- **Indentation**: Use 4 spaces (no tabs), proper indentation after file-scoped namespace
+- **Target Framework**: .NET 8.0 (`net8.0`)
+- **Language Version**: Latest (`latest`)
+- **Snippet tags**: Use format `[{Service}.dotnetv4.{ActionName}]` (e.g., `[Redshift.dotnetv4.CreateCluster]`)
#### Dependency Injection Patterns
```csharp
@@ -130,17 +134,28 @@ public class ExampleClass
#### Project Structure
```
-src/
-├── {Service}Examples/
-│ ├── Hello{Service}.cs
-│ ├── {Service}Actions.cs
-│ ├── {Service}Scenarios.cs
-│ └── {Service}Examples.csproj
-└── {Service}Examples.Tests/
- ├── {Service}Tests.cs
- └── {Service}Examples.Tests.csproj
+dotnetv4/{Service}/
+├── Actions/
+│ ├── Hello{Service}.cs # Hello example (with Main method)
+│ ├── {Service}Wrapper.cs # Service wrapper class
+│ └── {Service}Actions.csproj # Actions project file
+├── Scenarios/
+│ ├── {Service}Basics.cs # Basics scenario
+│ └── {Service}Basics.csproj # Scenarios project file
+├── Tests/
+│ ├── {Service}IntegrationTests.cs # Integration tests only
+│ └── {Service}Tests.csproj # Test project file
+└── {Service}Examples.sln # Service-specific solution file
```
+**CRITICAL Project Organization Rules:**
+- ✅ **Hello examples MUST be in the Actions project** with a Main method
+- ✅ **Integration tests ONLY** - no separate unit tests for wrapper methods
+- ✅ **No separate Hello project** - Hello is part of Actions
+- ✅ **No separate IntegrationTests project** - all tests in Tests project
+- ✅ **Create a service-specific solution file** named {Service}Examples.sln
+- ✅ **Solution must include**: Actions, Scenarios, and Tests projects only
+
#### Documentation Requirements
- **XML documentation**: Use `///` for class and method documentation
- **Parameter documentation**: Document all parameters with ``
@@ -176,21 +191,49 @@ src/
- ✅ **ALWAYS create examples in the dotnetv4 directory unless instructed otherwise**
- ✅ **ALWAYS follow the established .NET project structure**
- ✅ **ALWAYS use PascalCase for .NET identifiers**
+- ✅ **ALWAYS use file-scoped namespaces** (namespace Name; instead of namespace Name { })
- ✅ **ALWAYS use using statements for AWS client management**
- ✅ **ALWAYS include proper exception handling for AWS service calls**
- ✅ **ALWAYS test AWS credentials before assuming credential issues**
- ✅ **ALWAYS include comprehensive XML documentation**
- ✅ **ALWAYS use async/await patterns for AWS operations**
- ✅ **ALWAYS use dependency injection for AWS services**
-- ✅ **ALWAYS create a separate class in the Actions project for the Hello example**
-- ✅ **ALWAYS add project files to the main solution file DotNetV4Examples.sln**
+- ✅ **ALWAYS create Hello example in the Actions project** with a Main method
+- ✅ **ALWAYS create a service-specific solution file** (e.g., Redshift.sln)
+- ✅ **ALWAYS target .NET 8.0** with latest language version
+- ✅ **ALWAYS put integration tests in the Tests project** (no separate IntegrationTests project)
- ✅ **ALWAYS put print statements in the action methods if possible**
+- ✅ **ALWAYS update package versions** to avoid NU1603 warnings
### Project Configuration Requirements
-- **Target Framework**: Specify appropriate .NET version in .csproj
-- **AWS SDK packages**: Include specific AWS service NuGet packages
-- **Test packages**: Include xUnit and test runner packages
+- **Target Framework**: .NET 8.0 (`net8.0`)
+- **Language Version**: Latest (`latest`)
+- **AWS SDK packages**: Include specific AWS service NuGet packages (use latest versions)
+- **Test packages**: Include MSTest and test runner packages
- **Configuration**: Support for appsettings.json and environment variables
+- **Nullable**: Enable nullable reference types (`enable`)
+
+### Solution File Management
+Each service should have its own solution file in the service directory:
+
+```bash
+# Create solution file
+dotnet new sln -n {Service}Examples -o dotnetv4/{Service}
+
+# Add projects to solution
+dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Actions/{Service}Actions.csproj
+dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Scenarios/{Service}Basics.csproj
+dotnet sln dotnetv4/{Service}/{Service}Examples.sln add dotnetv4/{Service}/Tests/{Service}Tests.csproj
+
+# Build solution
+dotnet build dotnetv4/{Service}/{Service}Examples.sln
+```
+
+**Solution Structure:**
+- ✅ **3 projects only**: Actions, Scenarios, Tests
+- ✅ **No solution folders** - flat structure
+- ✅ **Service-specific naming**: {Service}Examples.sln (e.g., RedshiftExamples.sln)
+- ✅ **Located in service directory**: dotnetv4/{Service}/{Service}Examples.sln
### Integration with Knowledge Base
Before creating .NET code examples:
diff --git a/steering_docs/dotnet-tech/basics.md b/steering_docs/dotnet-tech/basics.md
index 98a94e968bc..b1d0ed452da 100644
--- a/steering_docs/dotnet-tech/basics.md
+++ b/steering_docs/dotnet-tech/basics.md
@@ -392,4 +392,396 @@ catch (Amazon{Service}Exception ex)
- Show before/after states as outlined in specification
- Provide context about service capabilities from specification
- Include tips and best practices mentioned in specification
-- Follow the educational flow described in specification structure
\ No newline at end of file
+- Follow the educational flow described in specification structure
+
+---
+
+#
+.NET v4 Project Organization Standards
+
+## Overview
+This section outlines the standardized project structure and organization for .NET v4 AWS SDK examples, based on the Redshift implementation.
+
+## Project Structure
+
+### Directory Layout
+```
+dotnetv4/{Service}/
+├── Actions/
+│ ├── Hello{Service}.cs # Hello example (with Main method)
+│ ├── {Service}Wrapper.cs # Service wrapper class
+│ └── {Service}Actions.csproj # Actions project file
+├── Scenarios/
+│ ├── {Service}Basics.cs # Basics scenario
+│ └── {Service}Basics.csproj # Scenarios project file
+├── Tests/
+│ ├── {Service}IntegrationTests.cs # Integration tests
+│ └── {Service}Tests.csproj # Test project file
+└── {Service}Examples.sln # Service-specific solution file
+```
+
+## Critical Organization Rules
+
+### ✅ DO
+- **Create service-specific solution files** in the service directory (e.g., `RedshiftExamples.sln`)
+- **Name solution files** as `{Service}Examples.sln` for consistency
+- **Include Hello example in Actions project** with a Main method
+- **Put integration tests in Tests project** (no separate IntegrationTests project)
+- **Use 3 projects only**: Actions, Scenarios, Tests
+- **Use flat solution structure** (no solution folders)
+- **Target .NET 8.0** with latest language version
+- **Use file-scoped namespaces** (namespace Name; instead of namespace Name { })
+- **Update package versions** to latest to avoid NU1603 warnings
+
+### ❌ DON'T
+- **Don't create separate Hello project** - it belongs in Actions
+- **Don't create separate IntegrationTests project** - use Tests project
+- **Don't use solution folders** - keep flat structure
+- **Don't target .NET Framework 4.8** - use .NET 8.0
+- **Don't use traditional namespaces** - use file-scoped
+- **Don't create unit tests with mocks** - use integration tests only
+
+## Project Configuration
+
+### Actions Project (.csproj)
+```xml
+
+
+
+ Exe
+ net8.0
+ enable
+ latest
+ {Service}Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
+```
+
+**Key Points:**
+- `Exe` - Required for Hello example Main method
+- `net8.0` - Use .NET 8.0
+- `latest` - Enable latest C# features
+- Include Microsoft.Extensions packages for dependency injection in Hello example
+- Use latest stable AWS SDK package versions (3.7.500 for AWS services)
+
+### Scenarios Project (.csproj)
+```xml
+
+
+
+ Exe
+ net8.0
+ enable
+ latest
+ {Service}Basics
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
+```
+
+### Tests Project (.csproj)
+```xml
+
+
+
+ net8.0
+ false
+ enable
+ latest
+ {Service}Tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ settings.json
+
+
+
+```
+
+**Key Points:**
+- Use MSTest framework (not xUnit)
+- No `` - tests are libraries
+- Reference Actions project only
+- Use latest stable test framework versions
+
+## Solution File Management
+
+### Creating Solution File
+```bash
+# Navigate to service directory
+cd dotnetv4/{Service}
+
+# Create solution file
+dotnet new sln -n {Service}Examples
+
+# Add projects
+dotnet sln {Service}Examples.sln add Actions/{Service}Actions.csproj
+dotnet sln {Service}Examples.sln add Scenarios/{Service}Basics.csproj
+dotnet sln {Service}Examples.sln add Tests/{Service}Tests.csproj
+
+# Build solution
+dotnet build {Service}Examples.sln
+```
+
+### Solution File Structure
+```
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33414.496
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "{Service}Actions", "Actions\{Service}Actions.csproj", "{GUID1}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "{Service}Basics", "Scenarios\{Service}Basics.csproj", "{GUID2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "{Service}Tests", "Tests\{Service}Tests.csproj", "{GUID3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {GUID1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {GUID1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {GUID1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {GUID1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {GUID2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {GUID2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {GUID2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {GUID2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {GUID3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {GUID3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {GUID3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {GUID3}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {SOLUTION-GUID}
+ EndGlobalSection
+EndGlobal
+```
+
+## Code Style Standards
+
+### File-Scoped Namespaces
+```csharp
+// ✅ CORRECT - File-scoped namespace
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+
+namespace RedshiftActions;
+
+public class HelloRedshift
+{
+ public static async Task Main(string[] args)
+ {
+ // Implementation
+ }
+}
+```
+
+```csharp
+// ❌ WRONG - Traditional namespace
+namespace RedshiftActions
+{
+ public class HelloRedshift
+ {
+ public static async Task Main(string[] args)
+ {
+ // Implementation
+ }
+ }
+}
+```
+
+### Indentation
+- Use 4 spaces (no tabs)
+- No extra indentation after file-scoped namespace
+- Consistent indentation throughout
+
+### Snippet Tags
+**CRITICAL**: Use the correct snippet tag format for all code examples:
+
+```csharp
+// ✅ CORRECT - Service name first, then dotnetv4
+// snippet-start:[{Service}.dotnetv4.CreateClusterSteering]
+public async Task CreateClusterAsync(...)
+{
+ // Implementation
+}
+// snippet-end:[{Service}.dotnetv4.CreateClusterSteering]
+
+// ❌ WRONG - Old format
+// snippet-start:[dotnetv4.example_code.redshift.CreateClusterSteering]
+// snippet-end:[dotnetv4.example_code.redshift.CreateClusterSteering]
+```
+
+**Format**: `[{Service}.dotnetv4.{ActionName}]`
+- Service name in PascalCase (e.g., Redshift, S3, DynamoDB)
+- Followed by `.dotnetv4.`
+- Action name in PascalCase (e.g., CreateCluster, ListBuckets, Hello)
+- For wrapper class: `[{Service}.dotnetv4.{Service}Wrapper]`
+- For scenarios: `[{Service}.dotnetv4.{Service}Scenario]`
+
+## Testing Standards
+
+### Integration Tests Only
+- **No unit tests with mocks** - test against real AWS services
+- **Use MSTest framework** - not xUnit
+- **Test complete workflows** - not individual methods
+- **Proper resource cleanup** - use ClassCleanup method
+- **Use TestCategory attributes** - for test organization
+
+### Test Class Structure
+```csharp
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+using System;
+using System.Threading.Tasks;
+using Amazon.Redshift;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using RedshiftActions;
+
+namespace RedshiftTests;
+
+[TestClass]
+public class RedshiftIntegrationTests
+{
+ private static RedshiftWrapper? _redshiftWrapper;
+
+ [ClassInitialize]
+ public static void ClassInitialize(TestContext context)
+ {
+ // Initialize clients
+ }
+
+ [ClassCleanup]
+ public static async Task ClassCleanup()
+ {
+ // Clean up resources
+ }
+
+ [TestMethod]
+ [TestCategory("Integration")]
+ public async Task TestOperation()
+ {
+ // Test implementation
+ }
+}
+```
+
+## Migration Checklist
+
+When updating existing projects to new standards:
+
+- [ ] Create service-specific solution file
+- [ ] Move Hello example to Actions project
+- [ ] Add `Exe` to Actions project
+- [ ] Consolidate integration tests into Tests project
+- [ ] Remove separate IntegrationTests project
+- [ ] Update all projects to target .NET 8.0
+- [ ] Add `latest` to all projects
+- [ ] Convert all namespaces to file-scoped
+- [ ] Fix indentation (remove extra level after namespace)
+- [ ] Update AWS SDK package versions to latest
+- [ ] Remove solution folders (use flat structure)
+- [ ] Update test framework to MSTest if using xUnit
+- [ ] Remove unit tests with mocks
+- [ ] Verify solution builds without warnings
+
+## Build and Test Commands
+
+```bash
+# Build solution
+dotnet build dotnetv4/{Service}/{Service}Examples.sln
+
+# Run all tests
+dotnet test dotnetv4/{Service}/{Service}Examples.sln
+
+# Run integration tests only
+dotnet test dotnetv4/{Service}/Tests/{Service}Tests.csproj --filter TestCategory=Integration
+
+# Run Hello example
+dotnet run --project dotnetv4/{Service}/Actions/{Service}Actions.csproj
+
+# Run Basics scenario
+dotnet run --project dotnetv4/{Service}/Scenarios/{Service}Basics.csproj
+```
+
+## Common Issues and Solutions
+
+### Issue: Package version warnings (NU1603)
+**Solution:** Update all AWS SDK packages to latest version (e.g., 3.7.401)
+
+### Issue: C# language version errors
+**Solution:** Add `latest` to all project files
+
+### Issue: Hello example won't run
+**Solution:** Ensure Actions project has `Exe`
+
+### Issue: Build errors after namespace conversion
+**Solution:** Check indentation - no extra level after file-scoped namespace
+
+### Issue: Tests not discovered
+**Solution:** Ensure using MSTest attributes ([TestClass], [TestMethod])
+
+## References
+- Main steering doc: `steering_docs/dotnet-tech.md`
+- Hello examples: `steering_docs/dotnet-tech/hello.md`
+- Tests: `steering_docs/dotnet-tech/tests.md`
+- Wrapper: `steering_docs/dotnet-tech/wrapper.md`
diff --git a/steering_docs/dotnet-tech/hello.md b/steering_docs/dotnet-tech/hello.md
index 2d50ef4a0c8..4e4b9278042 100644
--- a/steering_docs/dotnet-tech/hello.md
+++ b/steering_docs/dotnet-tech/hello.md
@@ -32,7 +32,28 @@ Generate simple "Hello" examples that demonstrate basic service connectivity and
## File Structure
```
dotnetv4/{Service}/Actions/
-├── Hello{Service}.cs # Hello example file
+├── Hello{Service}.cs # Hello example file (with Main method)
+├── {Service}Wrapper.cs # Service wrapper class
+└── {Service}Actions.csproj # Actions project file (OutputType=Exe)
+```
+
+**CRITICAL:**
+- ✅ Hello example MUST be in the Actions project
+- ✅ Actions project MUST have `Exe` to support Main method
+- ✅ NO separate Hello project should be created
+- ✅ Actions project MUST include Microsoft.Extensions packages for dependency injection
+
+**Required NuGet Packages for Actions Project:**
+```xml
+
+
+
+
+
+
+
+
+
```
## Hello Example Pattern
@@ -40,59 +61,83 @@ dotnetv4/{Service}/Actions/
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
-///
-/// Purpose
-///
-/// Shows how to get started with {AWS Service} by {basic operation description}.
-///
-
using System;
+using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.{Service};
using Amazon.{Service}.Model;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Console;
+using Microsoft.Extensions.Logging.Debug;
+
+namespace {Service}Actions;
-namespace Amazon.DocSamples.{Service}
+///
+/// Hello Amazon {Service} example.
+///
+public class Hello{Service}
{
- public class Hello{Service}
+ private static ILogger logger = null!;
+
+ // snippet-start:[{Service}.dotnetv4.Hello]
+ ///
+ /// Main method to run the Hello Amazon {Service} example.
+ ///
+ /// Command line arguments (not used).
+ public static async Task Main(string[] args)
{
- ///
- /// Use the AWS SDK for .NET to create an {AWS Service} client and
- /// {basic operation description}.
- /// This example uses the default settings specified in your shared credentials
- /// and config files.
- ///
- /// Command line arguments.
- public static async Task Main(string[] args)
+ // Set up dependency injection for Amazon {Service}.
+ using var host = Host.CreateDefaultBuilder(args)
+ .ConfigureLogging(logging =>
+ logging.AddFilter("System", LogLevel.Debug)
+ .AddFilter("Microsoft", LogLevel.Information)
+ .AddFilter("Microsoft", LogLevel.Trace))
+ .ConfigureServices((_, services) =>
+ services.AddAWSService())
+ .Build();
+
+ logger = LoggerFactory.Create(builder => { builder.AddConsole(); })
+ .CreateLogger();
+
+ var {service}Client = host.Services.GetRequiredService();
+
+ Console.Clear();
+ Console.WriteLine("Hello, Amazon {Service}! Let's list available {resources}:");
+ Console.WriteLine();
+
+ var {resources} = new List<{Resource}>();
+
+ try
{
- try
- {
- // Create service client
- using var {service}Client = new Amazon{Service}Client();
-
- // Perform the most basic operation for this service
- var response = await {service}Client.{BasicOperation}Async();
-
- Console.WriteLine("Hello, {AWS Service}!");
- // Display appropriate result information
-
- }
- catch (Amazon{Service}Exception ex)
+ // Use pagination to retrieve all {resources}
+ var {resources}Paginator = {service}Client.Paginators.List{Resources}(new List{Resources}Request());
+
+ await foreach (var response in {resources}Paginator.Responses)
{
- if (ex.ErrorCode == "UnauthorizedOperation")
- {
- Console.WriteLine("You don't have permission to access {AWS Service}.");
- }
- else
- {
- Console.WriteLine($"Couldn't access {AWS Service}. Error: {ex.Message}");
- }
+ {resources}.AddRange(response.{Resources});
}
- catch (Exception ex)
+
+ Console.WriteLine($"{{{resources}.Count}} {resource}(s) retrieved.");
+
+ foreach (var {resource} in {resources})
{
- Console.WriteLine($"An unexpected error occurred: {ex.Message}");
+ Console.WriteLine($"\t{{{resource}.Name}}");
}
}
+ catch (Amazon{Service}Exception ex)
+ {
+ logger.LogError("Error listing {resources}: {Message}", ex.Message);
+ Console.WriteLine($"Couldn't list {resources}. Error: {ex.Message}");
+ }
+ catch (Exception ex)
+ {
+ logger.LogError("An error occurred: {Message}", ex.Message);
+ Console.WriteLine($"An error occurred: {ex.Message}");
+ }
}
+ // snippet-end:[{Service}.dotnetv4.Hello]
}
```
@@ -114,13 +159,37 @@ namespace Amazon.DocSamples.{Service}
- ✅ **Must run without errors** (with proper credentials)
- ✅ **Must handle credential issues gracefully**
- ✅ **Must display meaningful output**
-- ✅ **Must use direct AWS SDK for .NET client calls**
+- ✅ **Must use dependency injection with Host.CreateDefaultBuilder**
+- ✅ **Must use pagination for list operations**
- ✅ **Must include proper XML documentation**
+- ✅ **Must use correct snippet tag format**: `[{Service}.dotnetv4.Hello]`
## Common Patterns
-- Always use `new Amazon{Service}Client()` directly
+- Use dependency injection with Host.CreateDefaultBuilder
+- Use pagination to retrieve all results
- Include comprehensive error handling with try-catch blocks
- Provide user-friendly output messages using Console.WriteLine
- Handle both service-specific and general exceptions
-- Keep it as simple as possible - no additional classes or complexity
-- Use async/await pattern for all AWS operations
\ No newline at end of file
+- Keep it as simple as possible - all logic in Main method
+- Use async/await pattern for all AWS operations
+
+## Snippet Tag Format
+**CRITICAL**: Use the correct snippet tag format:
+
+```csharp
+// ✅ CORRECT
+// snippet-start:[{Service}.dotnetv4.HelloSteering]
+public static async Task Main(string[] args)
+{
+ // Implementation
+}
+// snippet-end:[{Service}.dotnetv4.HelloSteering]
+
+// ❌ WRONG - Old format
+// snippet-start:[dotnetv4.example_code.{Service}.HelloSteering]
+// snippet-end:[dotnetv4.example_code.{Service}.HelloSteering]
+```
+
+**Format**: `[{Service}.dotnetv4.Hello]`
+- Service name in PascalCase (e.g., Redshift, S3, DynamoDB)
+- Always use `.dotnetv4.Hello` for Hello examples
\ No newline at end of file
diff --git a/steering_docs/dotnet-tech/tests.md b/steering_docs/dotnet-tech/tests.md
index 6576e7ba8c9..5d63bf90a6a 100644
--- a/steering_docs/dotnet-tech/tests.md
+++ b/steering_docs/dotnet-tech/tests.md
@@ -21,300 +21,212 @@ read_documentation("https://docs.aws.amazon.com/[service]/latest/[relevant-page]
**FAILURE TO COMPLETE KNOWLEDGE BASE CONSULTATION WILL RESULT IN INCORRECT CODE STRUCTURE**
## Purpose
-Generate comprehensive test suites including unit tests and integration tests using xUnit framework with proper mocking and AWS data structures.
+Generate integration test suites using xUnit framework to validate complete scenario workflows against real AWS services.
## Requirements
-- **Complete Data**: Use complete AWS data structures in tests
+- **Integration Tests Only**: Focus on end-to-end scenario testing, not unit tests
+- **Real AWS Services**: Tests run against actual AWS infrastructure
- **Proper Attributes**: Use xUnit attributes for test categorization
-- **Error Coverage**: Test all error conditions from specification
- **Async Testing**: Use async Task for async test methods
+- **Resource Cleanup**: Ensure proper cleanup of AWS resources after tests
## File Structure
```
dotnetv4/{Service}/Tests/
-├── {Service}Tests.csproj # Test project file
-├── {Service}Tests.cs # Unit and integration tests
+├── {Service}Tests.csproj # Test project file
+├── {Service}IntegrationTests.cs # Integration tests
```
+**CRITICAL:**
+- ✅ **Integration tests ONLY** - no separate unit tests for wrapper methods
+- ✅ **All tests in one project** - no separate IntegrationTests project
+- ✅ **Use xUnit framework** - not MSTest
+- ✅ **Test against real AWS** - not mocks
+
## Test Project Setup
### Step 1: Create Test Project File
```xml
+
-
net8.0
- enable
- enable
false
- true
+ enable
+ latest
+ {Service}Tests
-
-
-
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
-
-
+
+
+
+ PreserveNewest
+ settings.json
+
+
```
-### Step 2: Create Test Class Structure
-```csharp
-// dotnetv4/{Service}/Tests/{Service}Tests.cs
-using System;
-using System.Threading.Tasks;
-using Amazon.{Service};
-using Amazon.{Service}.Model;
-using Moq;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace Amazon.DocSamples.{Service}.Tests
-{
- public class {Service}Tests
- {
- private readonly ITestOutputHelper _output;
- private readonly Mock _mock{Service}Client;
- private readonly {Service}Wrapper _wrapper;
-
- public {Service}Tests(ITestOutputHelper output)
- {
- _output = output;
- _mock{Service}Client = new Mock();
- _wrapper = new {Service}Wrapper(_mock{Service}Client.Object);
- }
- }
-}
-```
+**Key Changes:**
+- ✅ Use xUnit packages (not MSTest)
+- ✅ Target .NET 8.0 with latest language version
+- ✅ Use latest AWS SDK package versions
+- ✅ Reference Actions project only (no Scenarios reference needed)
-## Unit Test Pattern
+### Step 2: Create Integration Test Class Structure
```csharp
-[Theory]
-[InlineData(null)]
-[InlineData("BadRequestException")]
-[InlineData("InternalServerErrorException")]
-public async Task Test{ActionName}Async_WithVariousConditions_ReturnsExpectedResult(string? errorCode)
-{
- // Arrange
- var paramValue = "test-value";
- var expectedResponse = new {ActionName}Response
- {
- ResponseKey = "response-value"
- };
-
- if (errorCode == null)
- {
- _mock{Service}Client
- .Setup(x => x.{ActionName}Async(It.IsAny<{ActionName}Request>(), default))
- .ReturnsAsync(expectedResponse);
- }
- else
- {
- _mock{Service}Client
- .Setup(x => x.{ActionName}Async(It.IsAny<{ActionName}Request>(), default))
- .ThrowsAsync(new Amazon{Service}Exception(errorCode));
- }
-
- // Act & Assert
- if (errorCode == null)
- {
- var result = await _wrapper.{ActionName}Async(paramValue);
- Assert.Equal("response-value", result.ResponseKey);
- }
- else
- {
- var exception = await Assert.ThrowsAsync(
- () => _wrapper.{ActionName}Async(paramValue));
- Assert.Equal(errorCode, exception.ErrorCode);
- }
-}
-```
-
-## Complete AWS Data Structures
-
-### CRITICAL: Use Complete AWS Response Data
-```csharp
-// ❌ WRONG - Minimal data that fails validation
-var findings = new List
-{
- new Finding { Id = "finding-1", Type = "SomeType", Severity = 8.0 }
-};
+// dotnetv4/{Service}/Tests/{Service}IntegrationTests.cs
+// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+// SPDX-License-Identifier: Apache-2.0
-// ✅ CORRECT - Complete AWS data structure
-var findings = new List
-{
- new Finding
- {
- Id = "finding-1",
- AccountId = "123456789012",
- Arn = "arn:aws:service:region:account:resource/id",
- Type = "SomeType",
- Severity = 8.0,
- CreatedAt = DateTime.Parse("2023-01-01T00:00:00.000Z"),
- UpdatedAt = DateTime.Parse("2023-01-01T00:00:00.000Z"),
- Region = "us-east-1",
- SchemaVersion = "2.0",
- Resource = new Resource { ResourceType = "Instance" }
- }
-};
-```
-
-## Integration Test Pattern
-Create a single integration test for the scenario by setting IsInteractive to false:
-
-```csharp
-using {Service}Basics;
-using Microsoft.Extensions.Logging;
-using Moq;
+using System.Threading.Tasks;
+using Amazon.{Service};
+using Amazon.{ServiceDataAPI};
+using {Service}Actions;
using Xunit;
namespace {Service}Tests;
///
-/// Integration tests for the Amazon {Service} Basics scenario.
+/// Integration tests for Amazon {Service} operations.
+/// These tests require actual AWS credentials and will create real AWS resources.
///
-public class {Service}BasicsTest
+public class {Service}IntegrationTests
{
///
- /// Verifies the scenario with an integration test. No errors should be logged.
+ /// Verifies the scenario with an integration test. No exceptions should be thrown.
///
- /// A task representing the asynchronous test operation.
+ /// Async task.
[Fact]
[Trait("Category", "Integration")]
- public async Task TestScenario()
+ public async Task TestScenarioIntegration()
{
- // Arrange.
- {Service}Basics.IsInteractive = false;
- var loggerMock = new Mock>();
- loggerMock.Setup(logger => logger.Log(
- It.Is(logLevel => logLevel == LogLevel.Error),
- It.IsAny(),
- It.Is((@object, @type) => true),
- It.IsAny(),
- It.IsAny>()));
-
- // Act.
- await {Service}Basics.Main(new string[] { "" });
-
- // Assert no exceptions or errors logged.
- loggerMock.Verify(logger => logger.Log(
- It.Is(logLevel => logLevel == LogLevel.Error),
- It.IsAny(),
- It.Is((@object, @type) => true),
- It.IsAny(),
- It.IsAny>()),
- Times.Never);
+ // Arrange
+ {Service}Basics.{Service}Basics.IsInteractive = false;
+
+ // Act
+ {Service}Basics.{Service}Basics.Wrapper = new {Service}Wrapper(
+ new Amazon{Service}Client(),
+ new Amazon{ServiceDataAPI}Client());
+
+ await {Service}Basics.{Service}Basics.RunScenarioAsync();
+
+ // Assert - if we get here without exceptions, the test passes
}
}
```
-## Additional Integration Test Patterns (Optional)
-If needed, you can add specific wrapper method tests:
+**Key Changes:**
+- ✅ Use file-scoped namespaces
+- ✅ Use xUnit attributes ([Fact], [Trait])
+- ✅ No mocking - test against real AWS services
+- ✅ Test runs the complete scenario end-to-end
+- ✅ Set IsInteractive = false for non-interactive test execution
+
+## Integration Test Patterns
+
+### Integration Test Pattern
+The integration test should run the complete scenario end-to-end:
```csharp
+///
+/// Verifies the scenario with an integration test. No exceptions should be thrown.
+///
+/// Async task.
[Fact]
[Trait("Category", "Integration")]
-public async Task Test{ActionName}Integration()
+public async Task TestScenarioIntegration()
{
// Arrange
- var wrapper = new {Service}Wrapper(new Amazon{Service}Client());
-
- // Act - This should not raise an exception
- var result = await wrapper.{ActionName}Async();
-
- // Assert - Verify result structure
- Assert.NotNull(result);
-}
+ {Service}Basics.{Service}Basics.IsInteractive = false;
-[Fact]
-[Trait("Category", "Integration")]
-public async Task TestResourceLifecycleIntegration()
-{
- // Arrange
- var wrapper = new {Service}Wrapper(new Amazon{Service}Client());
- string? resourceId = null;
-
- try
- {
- // Act - Create resource
- resourceId = await wrapper.CreateResourceAsync();
- Assert.NotNull(resourceId);
-
- // Use resource
- var result = await wrapper.GetResourceAsync(resourceId);
- Assert.NotNull(result);
- }
- finally
- {
- // Clean up
- if (!string.IsNullOrEmpty(resourceId))
- {
- try
- {
- await wrapper.DeleteResourceAsync(resourceId);
- }
- catch
- {
- // Ignore cleanup errors
- }
- }
- }
+ // Act
+ {Service}Basics.{Service}Basics.Wrapper = new {Service}Wrapper(
+ new Amazon{Service}Client(),
+ new Amazon{ServiceDataAPI}Client());
+
+ await {Service}Basics.{Service}Basics.RunScenarioAsync();
+
+ // Assert - if we get here without exceptions, the test passes
}
```
+**Key Points:**
+- ✅ Use `[Fact]` attribute for test methods
+- ✅ Use `[Trait("Category", "Integration")]` for categorization
+- ✅ Set `IsInteractive = false` to run without user input
+- ✅ Create real AWS clients (not mocked)
+- ✅ Call the scenario's `RunScenarioAsync()` method
+- ✅ Test passes if no exceptions are thrown
+
## Test Execution Commands
-### Unit Tests
+### All Tests
```bash
-dotnet test dotnetv4/{Service}/Tests/{Service}Tests.csproj --filter "Category!=Integration"
+dotnet test dotnetv4/{Service}/{Service}Examples.sln
```
-### Integration Tests (Runs Complete Scenario)
+### Integration Tests Only
```bash
-dotnet test dotnetv4/{Service}/Tests/{Service}Tests.csproj --filter Category=Integration
+dotnet test dotnetv4/{Service}/Tests/{Service}Tests.csproj --filter TestCategory=Integration
+```
+
+### Exclude Long-Running Tests
+```bash
+dotnet test dotnetv4/{Service}/Tests/{Service}Tests.csproj --filter "TestCategory=Integration&TestCategory!=LongRunning"
```
## Test Requirements Checklist
- ✅ **Test project file created** with proper dependencies
-- ✅ **Mock framework setup** (Moq for mocking AWS clients and loggers)
-- ✅ **Complete AWS data structures** in all tests
-- ✅ **Proper xUnit attributes** (`[Trait("Category", "Integration")]`)
-- ✅ **Error condition coverage** per specification
-- ✅ **Integration test sets IsInteractive to false** for automated testing
-- ✅ **Logger verification** to ensure no errors are logged
+- ✅ **xUnit framework** (not MSTest)
+- ✅ **Integration tests only** (no unit tests with mocks)
+- ✅ **Proper xUnit attributes** (`[Fact]`, `[Trait("Category", "Integration")]`)
+- ✅ **Test against real AWS services** (not mocks)
+- ✅ **Test runs complete scenario** via `RunScenarioAsync()`
- ✅ **Async test methods** using `async Task`
+- ✅ **File-scoped namespaces** for modern C# style
## Integration Test Focus
### Primary Test: Complete Scenario Integration
The main integration test should:
-- ✅ **Run the entire scenario** from start to finish
-- ✅ **Set IsInteractive to false** to automate the interactive parts
-- ✅ **Test against real AWS** services (not mocks)
-- ✅ **Verify no errors are logged** using mock logger verification
-- ✅ **Handle cleanup automatically** through scenario logic
-
-### Test Structure Priority
-1. **Integration Test** - Most important, tests complete workflow
-2. **Unit Tests** - Test individual wrapper methods
-3. **Additional Integration Tests** - Optional, for specific edge cases
+- ✅ **Run the entire scenario** from start to finish via `RunScenarioAsync()`
+- ✅ **Test against real AWS services** (not mocks)
+- ✅ **Set IsInteractive = false** for non-interactive execution
+- ✅ **Create real AWS clients** (not mocked)
+- ✅ **Use xUnit attributes** (`[Fact]`, `[Trait]`) for test organization
+- ✅ **Pass if no exceptions** are thrown during execution
+
+### Test Structure
+- **Single Integration Test** - Tests the complete scenario workflow
+- **No separate unit tests** - Focus on end-to-end integration only
+- **No mocking** - Use real AWS clients and services
## Common Test Failures to Avoid
-- ❌ **Not setting IsInteractive to false** in scenario integration tests
-- ❌ **Using incomplete AWS data structures** in unit tests
-- ❌ **Missing xUnit attributes** for integration tests
-- ❌ **Not verifying logger mock** to ensure no errors are logged
+- ❌ **Using mocks instead of real AWS services** in integration tests
+- ❌ **Missing xUnit attributes** (`[Fact]`, `[Trait]`) for integration tests
+- ❌ **Not setting IsInteractive = false** for non-interactive execution
- ❌ **Forgetting to set AWS region** in test clients
-- ❌ **Not testing all error conditions** from specification
-- ❌ **Not calling Main method properly** in scenario integration tests
-- ❌ **Missing proper async/await patterns** in test methods
\ No newline at end of file
+- ❌ **Missing proper async/await patterns** in test methods
+- ❌ **Using MSTest instead of xUnit** framework
+- ❌ **Creating separate IntegrationTests project** instead of using Tests project
+- ❌ **Not referencing the Scenarios project** when testing scenarios
\ No newline at end of file
diff --git a/steering_docs/dotnet-tech/wrapper.md b/steering_docs/dotnet-tech/wrapper.md
index fe858234bfe..93e215453ad 100644
--- a/steering_docs/dotnet-tech/wrapper.md
+++ b/steering_docs/dotnet-tech/wrapper.md
@@ -41,94 +41,86 @@ dotnetv4/{Service}/Actions/
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
-///
-/// Purpose
-///
-/// Shows how to use the AWS SDK for .NET with {AWS Service} to
-/// {service description and main use cases}.
-///
-
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.{Service};
using Amazon.{Service}.Model;
-using Microsoft.Extensions.Logging;
+using Amazon.{ServiceDataAPI};
+using Amazon.{ServiceDataAPI}.Model;
-namespace Amazon.DocSamples.{Service}
+namespace {Service}Actions;
+
+// snippet-start:[{Service}.dotnetv4.{Service}Wrapper]
+///
+/// Wrapper class for Amazon {Service} operations.
+///
+public class {Service}Wrapper
{
- // snippet-start:[dotnetv4.example_code.{service}.{Service}Wrapper]
+ private readonly Amazon{Service}Client _{service}Client;
+ private readonly Amazon{ServiceDataAPI}Client _{service}DataClient;
+
///
- /// Encapsulates {AWS Service} functionality.
+ /// Constructor for {Service}Wrapper.
///
- public class {Service}Wrapper
+ /// Amazon {Service} client.
+ /// Amazon {Service} Data API client.
+ public {Service}Wrapper(Amazon{Service}Client {service}Client, Amazon{ServiceDataAPI}Client {service}DataClient)
{
- private readonly IAmazon{Service} _{service}Client;
- private readonly ILogger<{Service}Wrapper> _logger;
-
- ///
- /// Initializes a new instance of the {Service}Wrapper class.
- ///
- /// The {AWS Service} client.
- /// The logger instance.
- public {Service}Wrapper(IAmazon{Service} {service}Client, ILogger<{Service}Wrapper> logger)
- {
- _{service}Client = {service}Client;
- _logger = logger;
- }
-
+ _{service}Client = {service}Client;
+ _{service}DataClient = {service}DataClient;
}
- // snippet-end:[dotnetv4.example_code.{service}.{Service}Wrapper]
// Individual action methods follow...
}
+// snippet-end:[{Service}.dotnetv4.{Service}Wrapper]
+```
+
+**Key Changes:**
+- ✅ Use file-scoped namespaces
+- ✅ Use concrete client types (not interfaces) for simpler construction
+- ✅ No logger dependency (use Console.WriteLine for output)
+- ✅ Include both service client and data API client if needed
```
## Action Method Pattern
```csharp
- // snippet-start:[dotnetv4.example_code.{service}.{ActionName}]
- ///
- /// {Action description}.
- ///
- /// Parameter description.
- /// Response description.
- public async Task<{ActionName}Response> {ActionMethod}Async(string param)
+ // snippet-start:[{Service}.dotnetv4.{ActionName}]
+ ///
+ /// {Action description}.
+ ///
+ /// Parameter description.
+ /// Response description.
+ public async Task<{ReturnType}> {ActionMethod}Async(string param)
+ {
+ try
{
- try
- {
- var request = new {ActionName}Request
- {
- Parameter = param
- };
-
- var response = await _{service}Client.{ActionName}Async(request);
- _logger.LogInformation("{Action} completed successfully", "{ActionName}");
- return response;
- }
- catch (Amazon{Service}Exception ex)
+ var request = new {ActionName}Request
{
- var errorCode = ex.ErrorCode;
- if (errorCode == "SpecificError")
- {
- _logger.LogError("Specific error handling message");
- }
- else if (errorCode == "AnotherSpecificError")
- {
- _logger.LogError("Another specific error handling message");
- }
- else
- {
- _logger.LogError("Error in {ActionName}: {Message}", ex.Message);
- }
- throw;
- }
+ Parameter = param
+ };
+
+ var response = await _{service}Client.{ActionName}Async(request);
+ Console.WriteLine($"{Action} completed successfully");
+ return response.{Property};
}
- // snippet-end:[dotnetv4.example_code.{service}.{ActionName}]
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Error in {ActionName}: {ex.Message}");
+ throw;
+ }
+ }
+ // snippet-end:[{Service}.dotnetv4.{ActionName}]
```
+**Key Changes:**
+- ✅ Use Console.WriteLine instead of logger
+- ✅ Simplified error handling (catch Exception instead of service-specific)
+- ✅ Return specific types instead of full response objects when appropriate
+
## Paginator Pattern for List Operations
```csharp
- // snippet-start:[dotnetv4.example_code.{service}.List{Resources}]
+ // snippet-start:[{Service}.dotnetv4.List{Resources}]
///
/// Lists all {resources} using pagination to retrieve complete results.
///
@@ -162,12 +154,12 @@ namespace Amazon.DocSamples.{Service}
throw;
}
}
- // snippet-end:[dotnetv4.example_code.{service}.List{Resources}]
+ // snippet-end:[{Service}.dotnetv4.List{Resources}]
```
## Paginator with Parameters Pattern
```csharp
- // snippet-start:[dotnetv4.example_code.{service}.List{Resources}WithFilter]
+ // snippet-start:[{Service}.dotnetv4.List{Resources}WithFilterSteering]
///
/// Lists {resources} with optional filtering, using pagination.
///
@@ -200,7 +192,7 @@ namespace Amazon.DocSamples.{Service}
throw;
}
}
- // snippet-end:[dotnetv4.example_code.{service}.List{Resources}WithFilter]
+ // snippet-end:[{Service}.dotnetv4.List{Resources}WithFilterSteering]
```
## Error Handling Requirements
@@ -290,4 +282,26 @@ await foreach (var response in itemsPaginator.Responses)
- Document return values with XML tags and descriptions
- Include usage examples in XML documentation where helpful
- Use proper snippet tags for documentation generation
-- Document pagination behavior in list method XML documentation
\ No newline at end of file
+- Document pagination behavior in list method XML documentation
+
+## Snippet Tag Format
+**CRITICAL**: Use the correct snippet tag format for all code examples:
+
+```csharp
+// ✅ CORRECT - Service name first, then dotnetv4
+// snippet-start:[{Service}.dotnetv4.CreateClusterSteering]
+public async Task CreateClusterAsync(...)
+{
+ // Implementation
+}
+// snippet-end:[{Service}.dotnetv4.CreateClusterSteering]
+
+// ❌ WRONG - Old format
+// snippet-start:[dotnetv4.example_code.{Service}.CreateClusterSteering]
+// snippet-end:[dotnetv4.example_code.{Service}.CreateClusterSteering]
+```
+
+**Format**: `[{Service}.dotnetv4.{ActionName}]`
+- Service name in PascalCase (e.g., Redshift, S3, DynamoDB)
+- Followed by `.dotnetv4.`
+- Action name in PascalCase (e.g., CreateCluster, ListBuckets, Hello)
\ No newline at end of file