diff --git a/CODEOWNERS b/CODEOWNERS
index 4c1260f6..584706b3 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -83,5 +83,13 @@
/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/ @Alirexaa
/tests/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.Tests/ @Alirexaa
/examples/postgres-ext/ @Alirexaa
+
+# CommunityToolkit.Aspire.Hosting.DbGate
+/src/CommunityToolkit.Aspire.Hosting.DbGate/ @Alirexaa
/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/ @Alirexaa
-/src/Shared/dbgate/ @Alirexaa
+/examples/dbgate/ @Alirexaa
+
+# CommunityToolkit.Aspire.Hosting.MongoDB.Extensions
+/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/ @Alirexaa
+/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/ @Alirexaa
+/examples/mongodb-ext/ @Alirexaa
\ No newline at end of file
diff --git a/CommunityToolkit.Aspire.sln b/CommunityToolkit.Aspire.sln
index 6b2c05c3..d5289aba 100644
--- a/CommunityToolkit.Aspire.sln
+++ b/CommunityToolkit.Aspire.sln
@@ -280,6 +280,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.RavenDB.ServiceDefaults", "examples\ravendb\CommunityToolkit.Aspire.Hosting.RavenDB.ServiceDefaults\CommunityToolkit.Aspire.Hosting.RavenDB.ServiceDefaults.csproj", "{3D076CFF-6482-4126-9F29-C7617E7D2F5B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.RavenDB.ApiService", "examples\ravendb\CommunityToolkit.Aspire.Hosting.RavenDB.ApiService\CommunityToolkit.Aspire.Hosting.RavenDB.ApiService.csproj", "{D214CBF5-D5E4-4641-868D-66B0C5337DD5}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.DbGate.Tests", "tests\CommunityToolkit.Aspire.Hosting.DbGate.Tests\CommunityToolkit.Aspire.Hosting.DbGate.Tests.csproj", "{BDAF7D27-C600-4419-9782-CF15BA5272E9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "postgres-ext", "postgres-ext", "{204BB8D8-04E3-4FE5-BB08-E793BF532F2F}"
@@ -302,6 +303,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.GoF
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests", "tests\CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests\CommunityToolkit.Aspire.Hosting.GoFeatureFlag.Tests.csproj", "{96458513-CAA8-498B-B4EE-3BF994140741}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.MongoDB.Extensions", "src\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.csproj", "{511D321E-277E-465A-AD62-B9971A6DD17E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.DbGate", "src\CommunityToolkit.Aspire.Hosting.DbGate\CommunityToolkit.Aspire.Hosting.DbGate.csproj", "{72054ADC-94AC-48D4-9718-72B70E830CD2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests", "tests\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests.csproj", "{57EF72E3-24DA-41B3-A3A1-B69E26421F68}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mongodb-ext", "mongodb-ext", "{8406E585-3329-48C5-B268-8C2140B720B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost", "examples\mongodb-ext\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost\CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost.csproj", "{A461FE7E-2458-428C-B794-6CC388031F16}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dbgate", "dbgate", "{50FBAF3E-E0BB-44FF-884F-660357C1CC54}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.DbGate.AppHost", "examples\dbgate\CommunityToolkit.Aspire.Hosting.DbGate.AppHost\CommunityToolkit.Aspire.Hosting.DbGate.AppHost.csproj", "{AFEAF08C-4959-4CF2-8806-4E75F8F73B2E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -800,6 +815,26 @@ Global
{96458513-CAA8-498B-B4EE-3BF994140741}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96458513-CAA8-498B-B4EE-3BF994140741}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96458513-CAA8-498B-B4EE-3BF994140741}.Release|Any CPU.Build.0 = Release|Any CPU
+ {511D321E-277E-465A-AD62-B9971A6DD17E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {511D321E-277E-465A-AD62-B9971A6DD17E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {511D321E-277E-465A-AD62-B9971A6DD17E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {511D321E-277E-465A-AD62-B9971A6DD17E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {72054ADC-94AC-48D4-9718-72B70E830CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {72054ADC-94AC-48D4-9718-72B70E830CD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {72054ADC-94AC-48D4-9718-72B70E830CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {72054ADC-94AC-48D4-9718-72B70E830CD2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {57EF72E3-24DA-41B3-A3A1-B69E26421F68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {57EF72E3-24DA-41B3-A3A1-B69E26421F68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {57EF72E3-24DA-41B3-A3A1-B69E26421F68}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {57EF72E3-24DA-41B3-A3A1-B69E26421F68}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A461FE7E-2458-428C-B794-6CC388031F16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A461FE7E-2458-428C-B794-6CC388031F16}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A461FE7E-2458-428C-B794-6CC388031F16}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A461FE7E-2458-428C-B794-6CC388031F16}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AFEAF08C-4959-4CF2-8806-4E75F8F73B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFEAF08C-4959-4CF2-8806-4E75F8F73B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFEAF08C-4959-4CF2-8806-4E75F8F73B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AFEAF08C-4959-4CF2-8806-4E75F8F73B2E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -944,16 +979,6 @@ Global
{BDAF7D27-C600-4419-9782-CF15BA5272E9} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{204BB8D8-04E3-4FE5-BB08-E793BF532F2F} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{356853EE-2C47-429C-B6CF-F3F76B6FFD91} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
- {BEA41234-DFF9-49AE-AD6C-42A9D54202E7} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
- {6782F1C1-5146-549F-82A8-60C82F1C7F16} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
- {97E455C1-C914-4C51-87A9-2C213CE2ED5B} = {6782F1C1-5146-549F-82A8-60C82F1C7F16}
- {5DF8F833-F6F8-4C9C-ABEC-80EC0C734A88} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
- {E48F6DDD-D62D-4723-810D-0F178C35E8B8} = {6782F1C1-5146-549F-82A8-60C82F1C7F16}
- {DD7042A1-8E44-40A8-B338-DC2F7B755702} = {6782F1C1-5146-549F-82A8-60C82F1C7F16}
- {E54E9DCA-1420-4306-83B6-D45D6EC49DBF} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
- {0E6EBCFB-DEF5-496C-95AF-00884826CFC8} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
- {861FE61C-90EE-49B0-BCC8-8417C293CC21} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
- {52846E18-99D1-4040-AF5F-17FC69198BCE} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{F926FB8A-77C6-4D39-AE44-9A7C11A3202D} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
{002E2F54-BB99-41F2-98D5-D6CC3B6A2845} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{FE9F4F1A-1115-4F18-96D8-C8A4AD50CDA5} = {002E2F54-BB99-41F2-98D5-D6CC3B6A2845}
@@ -962,6 +987,13 @@ Global
{C40D5274-DACF-4962-A58A-F08BDA80D0E2} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
{F4891827-BE07-4547-AF89-2734FB8DE6D5} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{96458513-CAA8-498B-B4EE-3BF994140741} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
+ {511D321E-277E-465A-AD62-B9971A6DD17E} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
+ {72054ADC-94AC-48D4-9718-72B70E830CD2} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
+ {57EF72E3-24DA-41B3-A3A1-B69E26421F68} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
+ {8406E585-3329-48C5-B268-8C2140B720B6} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
+ {A461FE7E-2458-428C-B794-6CC388031F16} = {8406E585-3329-48C5-B268-8C2140B720B6}
+ {50FBAF3E-E0BB-44FF-884F-660357C1CC54} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
+ {AFEAF08C-4959-4CF2-8806-4E75F8F73B2E} = {50FBAF3E-E0BB-44FF-884F-660357C1CC54}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {08B1D4B8-D2C5-4A64-BB8B-E1A2B29525F0}
diff --git a/Directory.Packages.props b/Directory.Packages.props
index fab4ba51..8619e75b 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -12,6 +12,7 @@
+
diff --git a/README.md b/README.md
index 1ab168f8..aa448bdc 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,8 @@ This repository contains the source code for the .NET Aspire Community Toolkit,
| - **Learn More**: [`RavenDB.Client`][ravendb-integration-docs]
- Stable 📦: [![CommunityToolkit.Aspire.RavenDB.Client][ravendb-client-shields]][ravendb-client-nuget]
- Preview 📦: [![CommunityToolkit.Aspire.RavenDB.Client][ravendb-client-shields-preview]][ravendb-client-nuget-preview] | An Aspire client integration for the [RavenDB.Client](https://www.nuget.org/packages/RavenDB.client) package. |
| - **Learn More**: [`Hosting.GoFeatureFlag`][go-feature-flag-integration-docs]
- Stable 📦: [![CommunityToolkit.Aspire.Hosting.GoFeatureFlag][go-feature-flag-shields]][go-feature-flag-nuget]
- Preview 📦: [![CommunityToolkit.Aspire.Hosting.GoFeatureFlag][go-feature-flag-shields-preview]][go-feature-flag-nuget-preview] | An Aspire hosting integration leveraging the [GoFeatureFlag](https://gofeatureflag.org/) container. |
| - **Learn More**: [`GoFeatureFlag`][go-feature-flag-integration-docs]
- Stable 📦: [![CommunityToolkit.Aspire.GoFeatureFlag][go-feature-flag-client-shields]][go-feature-flag-client-nuget]
- Preview 📦: [![CommunityToolkit.Aspire.GoFeatureFlag][go-feature-flag-client-shields-preview]][go-feature-flag-client-nuget-preview] | An Aspire client integration for the [GoFeatureFlag](https://github.com/open-feature/dotnet-sdk-contrib/tree/main/src/OpenFeature.Contrib.Providers.GOFeatureFlag) package. |
+| - **Learn More**: [`Hosting.MongoDB.Extensions`][mongodb-ext-integration-docs]
- Stable 📦: [![CommunityToolkit.Aspire.MongoDB.Extensions][mongodb-ext-shields]][mongodb-ext-nuget]
- Preview 📦: [![CommunityToolkit.Aspire.Hosting.MongoDB.Extensions][mongodb-ext-shields-preview]][mongodb-ext-nuget-preview] | An integration that contains some additional extensions for hosting MongoDB container. |
+| - **Learn More**: [`Hosting.PostgreSQL.Extensions`][postgres-ext-integration-docs]
- Stable 📦: [![CommunityToolkit.Aspire.PostgreSQL.Extensions][postgres-ext-shields]][postgres-ext-nuget]
- Preview 📦: [![CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions][postgres-ext-shields-preview]][postgres-ext-nuget-preview] | An integration that contains some additional extensions for hosting MongoDB container. |
## 🙌 Getting Started
@@ -204,3 +206,13 @@ This project is supported by the [.NET Foundation](https://dotnetfoundation.org)
[go-feature-flag-client-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.GoFeatureFlag/
[go-feature-flag-client-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.GoFeatureFlag?label=nuget%20(preview)
[go-feature-flag-client-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.GoFeatureFlag/absoluteLatest
+[mongodb-ext-integration-docs]: https://learn.microsoft.com/dotnet/aspire/community-toolkit/hosting-mongodb-extensions
+[mongodb-ext-shields]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions
+[mongodb-ext-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/
+[mongodb-ext-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions?label=nuget%20(preview)
+[mongodb-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/absoluteLatest
+[postgres-ext-integration-docs]: https://learn.microsoft.com/dotnet/aspire/community-toolkit/hosting-postgres-extensions
+[postgres-ext-shields]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions
+[postgres-ext-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/
+[postgres-ext-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions?label=nuget%20(preview)
+[postgres-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/absoluteLatest
diff --git a/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/CommunityToolkit.Aspire.Hosting.DbGate.AppHost.csproj b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/CommunityToolkit.Aspire.Hosting.DbGate.AppHost.csproj
new file mode 100644
index 00000000..84e37e61
--- /dev/null
+++ b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/CommunityToolkit.Aspire.Hosting.DbGate.AppHost.csproj
@@ -0,0 +1,22 @@
+
+
+
+
+ Exe
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Program.cs b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Program.cs
new file mode 100644
index 00000000..c6e37237
--- /dev/null
+++ b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Program.cs
@@ -0,0 +1,21 @@
+var builder = DistributedApplication.CreateBuilder(args);
+
+var postgres1 = builder.AddPostgres("postgres1")
+ .WithDbGate(c => c.WithHostPort(8068));
+postgres1.AddDatabase("db1");
+postgres1.AddDatabase("db2");
+
+var postgres2 = builder.AddPostgres("postgres2")
+ .WithDbGate();
+postgres2.AddDatabase("db3");
+postgres2.AddDatabase("db4");
+
+var mongodb1 = builder.AddMongoDB("mongodb1").WithDbGate();
+mongodb1.AddDatabase("db5");
+mongodb1.AddDatabase("db6");
+
+var mongodb2 = builder.AddMongoDB("mongodb2").WithDbGate();
+mongodb2.AddDatabase("db7");
+mongodb2.AddDatabase("db8");
+
+builder.Build().Run();
\ No newline at end of file
diff --git a/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Properties/launchSettings.json b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Properties/launchSettings.json
new file mode 100644
index 00000000..00e91269
--- /dev/null
+++ b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17202;http://localhost:15211",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21182",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22097"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15211",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19298",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20141"
+ }
+ }
+ }
+}
diff --git a/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/appsettings.json b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/appsettings.json
new file mode 100644
index 00000000..31c092aa
--- /dev/null
+++ b/examples/dbgate/CommunityToolkit.Aspire.Hosting.DbGate.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost.csproj b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost.csproj
new file mode 100644
index 00000000..a1ea1e7c
--- /dev/null
+++ b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost.csproj
@@ -0,0 +1,20 @@
+
+
+
+
+ Exe
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Program.cs b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Program.cs
new file mode 100644
index 00000000..b8abdf46
--- /dev/null
+++ b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Program.cs
@@ -0,0 +1,11 @@
+var builder = DistributedApplication.CreateBuilder(args);
+
+var mongodb1 = builder.AddMongoDB("mongodb1").WithDbGate(c => c.WithHostPort(8090));
+mongodb1.AddDatabase("db1");
+mongodb1.AddDatabase("db2");
+
+var mongodb2 = builder.AddMongoDB("mongodb2").WithDbGate();
+mongodb2.AddDatabase("db3");
+mongodb2.AddDatabase("db4");
+
+builder.Build().Run();
diff --git a/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Properties/launchSettings.json b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Properties/launchSettings.json
new file mode 100644
index 00000000..cad6fa6a
--- /dev/null
+++ b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17058;http://localhost:15268",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21178",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22264"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15268",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19258",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20169"
+ }
+ }
+ }
+}
diff --git a/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/appsettings.json b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/appsettings.json
new file mode 100644
index 00000000..31c092aa
--- /dev/null
+++ b/examples/mongodb-ext/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/examples/postgres-ext/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.AppHost/Program.cs b/examples/postgres-ext/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.AppHost/Program.cs
index b0d368c9..ffe82f81 100644
--- a/examples/postgres-ext/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.AppHost/Program.cs
+++ b/examples/postgres-ext/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.AppHost/Program.cs
@@ -1,7 +1,7 @@
var builder = DistributedApplication.CreateBuilder(args);
var postgres1 = builder.AddPostgres("postgres1")
- .WithDbGate(c=> c.WithHostPort(8068));
+ .WithDbGate(c => c.WithHostPort(8068));
postgres1.AddDatabase("db1");
postgres1.AddDatabase("db2");
diff --git a/src/CommunityToolkit.Aspire.Hosting.DbGate/CommunityToolkit.Aspire.Hosting.DbGate.csproj b/src/CommunityToolkit.Aspire.Hosting.DbGate/CommunityToolkit.Aspire.Hosting.DbGate.csproj
new file mode 100644
index 00000000..43aa0633
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.DbGate/CommunityToolkit.Aspire.Hosting.DbGate.csproj
@@ -0,0 +1,16 @@
+
+
+
+ hosting dbgate
+ A .NET Aspire integration for dbgate hosting.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Shared/dbgate/DbGateBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateBuilderExtensions.cs
similarity index 96%
rename from src/Shared/dbgate/DbGateBuilderExtensions.cs
rename to src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateBuilderExtensions.cs
index 122ceb8b..978aeb26 100644
--- a/src/Shared/dbgate/DbGateBuilderExtensions.cs
+++ b/src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateBuilderExtensions.cs
@@ -62,6 +62,9 @@ public static IResourceBuilder WithDataBindMount(this I
/// The resource builder.
/// The name of the resource. This name will be used as the connection string name when referenced in a dependency.
/// The host port to bind the underlying container to.
+ ///
+ /// Multiple calls will return the same resource builder instance.
+ ///
/// A reference to the .
public static IResourceBuilder AddDbGate(this IDistributedApplicationBuilder builder, [ResourceName] string name, int? port = null)
{
diff --git a/src/Shared/dbgate/DbGateContainerImageTags.cs b/src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateContainerImageTags.cs
similarity index 100%
rename from src/Shared/dbgate/DbGateContainerImageTags.cs
rename to src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateContainerImageTags.cs
diff --git a/src/Shared/dbgate/DbGateContainerResource.cs b/src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateContainerResource.cs
similarity index 100%
rename from src/Shared/dbgate/DbGateContainerResource.cs
rename to src/CommunityToolkit.Aspire.Hosting.DbGate/DbGateContainerResource.cs
diff --git a/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Shipped.txt b/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Shipped.txt
new file mode 100644
index 00000000..7dc5c581
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Shipped.txt
@@ -0,0 +1 @@
+#nullable enable
diff --git a/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Unshipped.txt b/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Unshipped.txt
new file mode 100644
index 00000000..da1165fe
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.DbGate/PublicAPI.Unshipped.txt
@@ -0,0 +1,8 @@
+Aspire.Hosting.ApplicationModel.DbGateContainerResource
+Aspire.Hosting.ApplicationModel.DbGateContainerResource.DbGateContainerResource(string! name) -> void
+Aspire.Hosting.ApplicationModel.DbGateContainerResource.PrimaryEndpoint.get -> Aspire.Hosting.ApplicationModel.EndpointReference!
+Aspire.Hosting.DbGateBuilderExtensions
+static Aspire.Hosting.DbGateBuilderExtensions.AddDbGate(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, int? port = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
+static Aspire.Hosting.DbGateBuilderExtensions.WithDataBindMount(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, string! source, bool isReadOnly = false) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
+static Aspire.Hosting.DbGateBuilderExtensions.WithDataVolume(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, string? name = null, bool isReadOnly = false) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
+static Aspire.Hosting.DbGateBuilderExtensions.WithHostPort(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, int? port) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
\ No newline at end of file
diff --git a/src/CommunityToolkit.Aspire.Hosting.DbGate/README.md b/src/CommunityToolkit.Aspire.Hosting.DbGate/README.md
new file mode 100644
index 00000000..7b5d65ce
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.DbGate/README.md
@@ -0,0 +1 @@
+This package is designed to be used internally by the community toolkit and is not intended to be used directly in the application code.
diff --git a/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.csproj b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.csproj
new file mode 100644
index 00000000..6eeefb08
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.csproj
@@ -0,0 +1,21 @@
+
+
+
+ hosting mongodb dbgate
+ A .NET Aspire integration for extending mongodb hosting.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/MongoDBBuilderExtensions.cs b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/MongoDBBuilderExtensions.cs
new file mode 100644
index 00000000..43088201
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/MongoDBBuilderExtensions.cs
@@ -0,0 +1,94 @@
+using Aspire.Hosting.ApplicationModel;
+using System.Text;
+
+namespace Aspire.Hosting;
+
+///
+/// Provides extension methods for adding MongoDB resources to an .
+///
+public static class MongoDBBuilderExtensions
+{
+ ///
+ /// Adds an administration and development platform for MongoDB to the application model using DbGate.
+ ///
+ ///
+ /// This version of the package defaults to the tag of the container image.
+ ///
+ /// The MongoDB server resource builder.
+ /// Configuration callback for DbGate container resource.
+ /// The name of the container (Optional).
+ ///
+ /// Use in application host with a MongoDB resource
+ ///
+ /// var builder = DistributedApplication.CreateBuilder(args);
+ ///
+ /// var mongodb = builder.AddMongoDB("mongodb")
+ /// .WithDbGate();
+ /// var db = mongodb.AddDatabase("db");
+ ///
+ /// var api = builder.AddProject<Projects.Api>("api")
+ /// .WithReference(db);
+ ///
+ /// builder.Build().Run();
+ ///
+ ///
+ /// A reference to the .
+ public static IResourceBuilder WithDbGate(this IResourceBuilder builder, Action>? configureContainer = null, string? containerName = null)
+ {
+ ArgumentNullException.ThrowIfNull(builder);
+
+ containerName ??= $"{builder.Resource.Name}-dbgate";
+
+ var dbGateBuilder = DbGateBuilderExtensions.AddDbGate(builder.ApplicationBuilder, containerName);
+
+ dbGateBuilder
+ .WithEnvironment(context => ConfigureDbGateContainer(context, builder.ApplicationBuilder))
+ .WaitFor(builder);
+
+ configureContainer?.Invoke(dbGateBuilder);
+
+ return builder;
+ }
+
+ private static void ConfigureDbGateContainer(EnvironmentCallbackContext context, IDistributedApplicationBuilder applicationBuilder)
+ {
+ var mongoDBInstances = applicationBuilder.Resources.OfType();
+
+ var counter = 1;
+
+ // Multiple WithDbGate calls will be ignored
+ if (context.EnvironmentVariables.ContainsKey($"LABEL_mongodb{counter}"))
+ {
+ return;
+ }
+
+ foreach (var mongoDBServer in mongoDBInstances)
+ {
+ // DbGate assumes MongoDB is being accessed over a default Aspire container network and hardcodes the resource address
+ // This will need to be refactored once updated service discovery APIs are available
+ context.EnvironmentVariables.Add($"LABEL_mongodb{counter}", mongoDBServer.Name);
+ context.EnvironmentVariables.Add($"URL_mongodb{counter}", mongoDBServer.ConnectionStringExpression);
+ context.EnvironmentVariables.Add($"ENGINE_mongodb{counter}", "mongo@dbgate-plugin-mongo");
+
+ counter++;
+ }
+
+ var instancesCount = mongoDBInstances.Count();
+ if (instancesCount > 0)
+ {
+ var strBuilder = new StringBuilder();
+ strBuilder.AppendJoin(',', Enumerable.Range(1, instancesCount).Select(i => $"mongodb{i}"));
+ var connections = strBuilder.ToString();
+
+ string CONNECTIONS = context.EnvironmentVariables.GetValueOrDefault("CONNECTIONS")?.ToString() ?? string.Empty;
+ if (string.IsNullOrEmpty(CONNECTIONS))
+ {
+ context.EnvironmentVariables["CONNECTIONS"] = connections;
+ }
+ else
+ {
+ context.EnvironmentVariables["CONNECTIONS"] += $",{connections}";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Shipped.txt b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Shipped.txt
new file mode 100644
index 00000000..7dc5c581
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Shipped.txt
@@ -0,0 +1 @@
+#nullable enable
diff --git a/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Unshipped.txt b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Unshipped.txt
new file mode 100644
index 00000000..740a292b
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/PublicAPI.Unshipped.txt
@@ -0,0 +1,2 @@
+Aspire.Hosting.MongoDBBuilderExtensions
+static Aspire.Hosting.MongoDBBuilderExtensions.WithDbGate(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, System.Action!>? configureContainer = null, string? containerName = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
\ No newline at end of file
diff --git a/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/README.md b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/README.md
new file mode 100644
index 00000000..4f05d2be
--- /dev/null
+++ b/src/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions/README.md
@@ -0,0 +1,32 @@
+# CommunityToolkit.Aspire.Hosting.MongoDB.Extensions library
+
+This integration contains extensions for the [MongoDB hosting package](https://nuget.org/packages/Aspire.Hosting.MongoDB) for .NET Aspire.
+
+The integration provides support for running [DbGate](https://github.com/dbgate/dbgate) to interact with the MongoDB database.
+
+## Getting Started
+
+### Install the package
+
+In your AppHost project, install the package using the following command:
+
+```dotnetcli
+dotnet add package CommunityToolkit.Aspire.Hosting.MongoDB.Extensions
+```
+
+### Example usage
+
+Then, in the _Program.cs_ file of `AppHost`, define an MongoDB resource, then call `AddMongoDB`:
+
+```csharp
+var mongodb = builder.AddMongoDB("mongodb")
+ .WithDbGate();
+```
+
+## Additional Information
+
+https://learn.microsoft.com/dotnet/aspire/community-toolkit/hosting-mongodb-extensions
+
+## Feedback & contributing
+
+https://github.com/CommunityToolkit/Aspire
\ No newline at end of file
diff --git a/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.csproj b/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.csproj
index f0db8c3c..6b738bac 100644
--- a/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.csproj
+++ b/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions.csproj
@@ -12,9 +12,10 @@
-
-
-
+
+
+
+
diff --git a/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/PublicAPI.Unshipped.txt b/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/PublicAPI.Unshipped.txt
index 749bc5dd..0fa5e608 100644
--- a/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/PublicAPI.Unshipped.txt
+++ b/src/CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions/PublicAPI.Unshipped.txt
@@ -1,10 +1,2 @@
-Aspire.Hosting.ApplicationModel.DbGateContainerResource
-Aspire.Hosting.ApplicationModel.DbGateContainerResource.DbGateContainerResource(string! name) -> void
-Aspire.Hosting.ApplicationModel.DbGateContainerResource.PrimaryEndpoint.get -> Aspire.Hosting.ApplicationModel.EndpointReference!
-Aspire.Hosting.DbGateBuilderExtensions
Aspire.Hosting.PostgresBuilderExtensions
-static Aspire.Hosting.DbGateBuilderExtensions.AddDbGate(this Aspire.Hosting.IDistributedApplicationBuilder! builder, string! name, int? port = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
-static Aspire.Hosting.DbGateBuilderExtensions.WithDataBindMount(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, string! source, bool isReadOnly = false) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
-static Aspire.Hosting.DbGateBuilderExtensions.WithDataVolume(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, string? name = null, bool isReadOnly = false) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
-static Aspire.Hosting.DbGateBuilderExtensions.WithHostPort(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, int? port) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
static Aspire.Hosting.PostgresBuilderExtensions.WithDbGate(this Aspire.Hosting.ApplicationModel.IResourceBuilder! builder, System.Action!>? configureContainer = null, string? containerName = null) -> Aspire.Hosting.ApplicationModel.IResourceBuilder!
\ No newline at end of file
diff --git a/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AddDbGateTests.cs b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AddDbGateTests.cs
index ded8bbad..57e85db2 100644
--- a/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AddDbGateTests.cs
+++ b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AddDbGateTests.cs
@@ -169,4 +169,177 @@ public void VerifyWithData(bool useVolume)
Assert.False(mountAnnotation.IsReadOnly);
}
}
+
+ [Fact]
+ public async Task WithDbGateShouldAddAnnotationsForMultipleDatabaseTypes()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+
+ var mongodbResourceBuilder1 = builder.AddMongoDB("mongodb1")
+ .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 27017))
+ .WithDbGate();
+
+ var mongodbResource1 = mongodbResourceBuilder1.Resource;
+
+ var mongodbResourceBuilder2 = builder.AddMongoDB("mongodb2")
+ .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 27018))
+ .WithDbGate();
+
+ var mongodbResource2 = mongodbResourceBuilder2.Resource;
+
+ var postgresResourceBuilder1 = builder.AddPostgres("postgres1")
+ .WithDbGate();
+
+ var postgresResource1 = postgresResourceBuilder1.Resource;
+
+ var postgresResourceBuilder2 = builder.AddPostgres("postgres2")
+ .WithDbGate();
+
+ var postgresResource2 = postgresResourceBuilder2.Resource;
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+
+ Assert.NotNull(dbGateResource);
+
+ Assert.Equal("mongodb1-dbgate", dbGateResource.Name);
+
+ var envs = await dbGateResource.GetEnvironmentVariableValuesAsync();
+
+ Assert.NotEmpty(envs);
+ Assert.Collection(envs,
+ item =>
+ {
+ Assert.Equal("LABEL_mongodb1", item.Key);
+ Assert.Equal(mongodbResource1.Name, item.Value);
+ },
+ async item =>
+ {
+ Assert.Equal("URL_mongodb1", item.Key);
+ Assert.Equal(await mongodbResource1.ConnectionStringExpression.GetValueAsync(default), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_mongodb1", item.Key);
+ Assert.Equal("mongo@dbgate-plugin-mongo", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("LABEL_mongodb2", item.Key);
+ Assert.Equal(mongodbResource2.Name, item.Value);
+ },
+ async item =>
+ {
+ Assert.Equal("URL_mongodb2", item.Key);
+ Assert.Equal(await mongodbResource2.ConnectionStringExpression.GetValueAsync(default), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_mongodb2", item.Key);
+ Assert.Equal("mongo@dbgate-plugin-mongo", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("CONNECTIONS", item.Key);
+ Assert.Equal("mongodb1,mongodb2,postgres1,postgres2", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("LABEL_postgres1", item.Key);
+ Assert.Equal(postgresResource1.Name, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("SERVER_postgres1", item.Key);
+ Assert.Equal(postgresResource1.Name, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("USER_postgres1", item.Key);
+ Assert.Equal("postgres", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("PASSWORD_postgres1", item.Key);
+ Assert.Equal(postgresResource1.PasswordParameter.Value, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("PORT_postgres1", item.Key);
+ Assert.Equal(postgresResource1.PrimaryEndpoint.TargetPort.ToString(), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_postgres1", item.Key);
+ Assert.Equal("postgres@dbgate-plugin-postgres", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("LABEL_postgres2", item.Key);
+ Assert.Equal(postgresResource2.Name, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("SERVER_postgres2", item.Key);
+ Assert.Equal(postgresResource2.Name, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("USER_postgres2", item.Key);
+ Assert.Equal("postgres", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("PASSWORD_postgres2", item.Key);
+ Assert.Equal(postgresResource2.PasswordParameter.Value, item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("PORT_postgres2", item.Key);
+ Assert.Equal(postgresResource2.PrimaryEndpoint.TargetPort.ToString(), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_postgres2", item.Key);
+ Assert.Equal("postgres@dbgate-plugin-postgres", item.Value);
+ });
+ }
+
+ [Fact]
+ public void WithDbGateShouldShouldAddOneDbGateResourceForMultipleDatabaseTypes()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+
+ var mongodbResourceBuilder1 = builder.AddMongoDB("mongodb1")
+ .WithDbGate();
+
+ var mongodbResource1 = mongodbResourceBuilder1.Resource;
+
+ var mongodbResourceBuilder2 = builder.AddMongoDB("mongodb2")
+ .WithDbGate();
+
+ var mongodbResource2 = mongodbResourceBuilder2.Resource;
+
+ var postgresResourceBuilder1 = builder.AddPostgres("postgres1")
+ .WithDbGate();
+
+ var postgresResource1 = postgresResourceBuilder1.Resource;
+
+ var postgresResourceBuilder2 = builder.AddPostgres("postgres2")
+ .WithDbGate();
+
+ var postgresResource2 = postgresResourceBuilder2.Resource;
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+
+ var containerResource = Assert.Single(appModel.Resources.OfType());
+ Assert.Equal("mongodb1-dbgate", containerResource.Name);
+ }
}
diff --git a/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AppHostTests.cs b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AppHostTests.cs
new file mode 100644
index 00000000..25c4250e
--- /dev/null
+++ b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/AppHostTests.cs
@@ -0,0 +1,20 @@
+using CommunityToolkit.Aspire.Testing;
+using Aspire.Components.Common.Tests;
+
+namespace CommunityToolkit.Aspire.Hosting.DbGate.Tests;
+
+[RequiresDocker]
+public class AppHostTests(AspireIntegrationTestFixture fixture) : IClassFixture>
+{
+ [Fact]
+ public async Task ResourceStartsAndRespondsOk()
+ {
+ var resourceName = "postgres1-dbgate";
+ await fixture.ResourceNotificationService.WaitForResourceHealthyAsync(resourceName).WaitAsync(TimeSpan.FromMinutes(5));
+ var httpClient = fixture.CreateHttpClient(resourceName);
+
+ var response = await httpClient.GetAsync("/");
+
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ }
+}
\ No newline at end of file
diff --git a/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests.csproj b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests.csproj
index 1d03f7f9..5f9c01c7 100644
--- a/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests.csproj
+++ b/tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests/CommunityToolkit.Aspire.Hosting.DbGate.Tests.csproj
@@ -1,11 +1,11 @@

+
+
-
-
-
+
diff --git a/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/AppHostTests.cs b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/AppHostTests.cs
new file mode 100644
index 00000000..ecb50be9
--- /dev/null
+++ b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/AppHostTests.cs
@@ -0,0 +1,20 @@
+using CommunityToolkit.Aspire.Testing;
+using Aspire.Components.Common.Tests;
+
+namespace CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests;
+
+[RequiresDocker]
+public class AppHostTests(AspireIntegrationTestFixture fixture) : IClassFixture>
+{
+ [Fact]
+ public async Task ResourceStartsAndRespondsOk()
+ {
+ var resourceName = "mongodb1-dbgate";
+ await fixture.ResourceNotificationService.WaitForResourceHealthyAsync(resourceName).WaitAsync(TimeSpan.FromMinutes(5));
+ var httpClient = fixture.CreateHttpClient(resourceName);
+
+ var response = await httpClient.GetAsync("/");
+
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ }
+}
\ No newline at end of file
diff --git a/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests.csproj b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests.csproj
new file mode 100644
index 00000000..8f041930
--- /dev/null
+++ b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests.csproj
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/ResourceCreationTests.cs b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/ResourceCreationTests.cs
new file mode 100644
index 00000000..bef81aba
--- /dev/null
+++ b/tests/CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests/ResourceCreationTests.cs
@@ -0,0 +1,173 @@
+using Aspire.Hosting;
+
+namespace CommunityToolkit.Aspire.Hosting.MongoDB.Extensions.Tests;
+
+public class ResourceCreationTests
+{
+ [Fact]
+ public async Task WithDbGateAddsAnnotations()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+
+ var mongodbResourceBuilder = builder.AddMongoDB("mongodb")
+ .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 27017))
+ .WithDbGate();
+
+ var mongodbResource = mongodbResourceBuilder.Resource;
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+
+ Assert.NotNull(dbGateResource);
+
+ Assert.Equal("mongodb-dbgate", dbGateResource.Name);
+
+ var envs = await dbGateResource.GetEnvironmentVariableValuesAsync();
+
+ Assert.NotEmpty(envs);
+ Assert.Collection(envs,
+ item =>
+ {
+ Assert.Equal("LABEL_mongodb1", item.Key);
+ Assert.Equal(mongodbResource.Name, item.Value);
+ },
+ async item =>
+ {
+ Assert.Equal("URL_mongodb1", item.Key);
+ Assert.Equal(await mongodbResource.ConnectionStringExpression.GetValueAsync(default), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_mongodb1", item.Key);
+ Assert.Equal("mongo@dbgate-plugin-mongo", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("CONNECTIONS", item.Key);
+ Assert.Equal("mongodb1", item.Value);
+ });
+ }
+
+ [Fact]
+ public void MultipleWithDbGateCallsAddsOneDbGateResource()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+ builder.AddMongoDB("mongodb1").WithDbGate();
+ builder.AddMongoDB("mongodb2").WithDbGate();
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+ Assert.NotNull(dbGateResource);
+
+ Assert.Equal("mongodb1-dbgate", dbGateResource.Name);
+ }
+
+ [Fact]
+ public void WithDbGateShouldChangeDbGateHostPort()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+ var mongodbResourceBuilder = builder.AddMongoDB("mongodb")
+ .WithDbGate(c => c.WithHostPort(8068));
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+ Assert.NotNull(dbGateResource);
+
+ var primaryEndpoint = dbGateResource.Annotations.OfType().Single();
+ Assert.Equal(8068, primaryEndpoint.Port);
+ }
+
+ [Fact]
+ public void WithDbGateShouldChangeDbGateContainerImageTag()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+ var mongodbResourceBuilder = builder.AddMongoDB("mongodb")
+ .WithDbGate(c => c.WithImageTag("manualTag"));
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+ Assert.NotNull(dbGateResource);
+
+ var containerImageAnnotation = dbGateResource.Annotations.OfType().Single();
+ Assert.Equal("manualTag", containerImageAnnotation.Tag);
+ }
+
+ [Fact]
+ public async Task WithDbGateAddsAnnotationsForMultipleMongoDBResource()
+ {
+ var builder = DistributedApplication.CreateBuilder();
+
+ var mongodbResourceBuilder1 = builder.AddMongoDB("mongodb1")
+ .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 27017))
+ .WithDbGate();
+
+ var mongodbResource1 = mongodbResourceBuilder1.Resource;
+
+ var mongodbResourceBuilder2 = builder.AddMongoDB("mongodb2")
+ .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 27018))
+ .WithDbGate();
+
+ var mongodbResource2 = mongodbResourceBuilder2.Resource;
+
+ using var app = builder.Build();
+
+ var appModel = app.Services.GetRequiredService();
+
+ var dbGateResource = appModel.Resources.OfType().SingleOrDefault();
+
+ Assert.NotNull(dbGateResource);
+
+ Assert.Equal("mongodb1-dbgate", dbGateResource.Name);
+
+ var envs = await dbGateResource.GetEnvironmentVariableValuesAsync();
+
+ Assert.NotEmpty(envs);
+ Assert.Collection(envs,
+ item =>
+ {
+ Assert.Equal("LABEL_mongodb1", item.Key);
+ Assert.Equal(mongodbResource1.Name, item.Value);
+ },
+ async item =>
+ {
+ Assert.Equal("URL_mongodb1", item.Key);
+ Assert.Equal(await mongodbResource1.ConnectionStringExpression.GetValueAsync(default), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_mongodb1", item.Key);
+ Assert.Equal("mongo@dbgate-plugin-mongo", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("LABEL_mongodb2", item.Key);
+ Assert.Equal(mongodbResource2.Name, item.Value);
+ },
+ async item =>
+ {
+ Assert.Equal("URL_mongodb2", item.Key);
+ Assert.Equal(await mongodbResource2.ConnectionStringExpression.GetValueAsync(default), item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("ENGINE_mongodb2", item.Key);
+ Assert.Equal("mongo@dbgate-plugin-mongo", item.Value);
+ },
+ item =>
+ {
+ Assert.Equal("CONNECTIONS", item.Key);
+ Assert.Equal("mongodb1,mongodb2", item.Value);
+ });
+ }
+}