├── .devcontainer ├── devcontainer.json └── on-create.sh ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── 1-intro ├── README.md └── images │ └── ep1_thumb_yt_small.jpg ├── 2-monolith-on-aca ├── README.md ├── images │ ├── ep2_thumb_yt_small.jpg │ └── local-app.png └── sample │ ├── .dockerignore │ ├── Dockerfile.store │ ├── eShopLite.sln │ └── src │ └── eShopLite.Store │ ├── ApiClients │ ├── ProductApiClient.cs │ └── StoreInfoApiClient.cs │ ├── Components │ ├── App.razor │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Error.razor │ │ ├── Home.razor │ │ ├── Products.razor │ │ └── Stores.razor │ ├── Routes.razor │ └── _Imports.razor │ ├── DataEntities │ ├── Product.cs │ └── StoreInfo.cs │ ├── Endpoints │ ├── ProductEndpoints.cs │ └── StoreInfoEndpoints.cs │ ├── Extensions │ ├── ProductDbContextExtensions.cs │ └── StoreInfoDbContextExtensions.cs │ ├── ProductData │ ├── DbInitializer.cs │ └── ProductDbContext.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── StoreInfoData │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ ├── app.css │ ├── favicon.png │ ├── images │ ├── product1.png │ ├── product2.png │ ├── product3.png │ ├── product4.png │ ├── product5.png │ ├── product6.png │ ├── product7.png │ ├── product8.png │ └── product9.png │ └── lib │ └── bootstrap │ └── dist │ ├── css │ ├── bootstrap-grid.css │ ├── bootstrap-grid.css.map │ ├── bootstrap-grid.min.css │ ├── bootstrap-grid.min.css.map │ ├── bootstrap-grid.rtl.css │ ├── bootstrap-grid.rtl.css.map │ ├── bootstrap-grid.rtl.min.css │ ├── bootstrap-grid.rtl.min.css.map │ ├── bootstrap-reboot.css │ ├── bootstrap-reboot.css.map │ ├── bootstrap-reboot.min.css │ ├── bootstrap-reboot.min.css.map │ ├── bootstrap-reboot.rtl.css │ ├── bootstrap-reboot.rtl.css.map │ ├── bootstrap-reboot.rtl.min.css │ ├── bootstrap-reboot.rtl.min.css.map │ ├── bootstrap-utilities.css │ ├── bootstrap-utilities.css.map │ ├── bootstrap-utilities.min.css │ ├── bootstrap-utilities.min.css.map │ ├── bootstrap-utilities.rtl.css │ ├── bootstrap-utilities.rtl.css.map │ ├── bootstrap-utilities.rtl.min.css │ ├── bootstrap-utilities.rtl.min.css.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ ├── bootstrap.rtl.css │ ├── bootstrap.rtl.css.map │ ├── bootstrap.rtl.min.css │ └── bootstrap.rtl.min.css.map │ └── js │ ├── bootstrap.bundle.js │ ├── bootstrap.bundle.js.map │ ├── bootstrap.bundle.min.js │ ├── bootstrap.bundle.min.js.map │ ├── bootstrap.esm.js │ ├── bootstrap.esm.js.map │ ├── bootstrap.esm.min.js │ ├── bootstrap.esm.min.js.map │ ├── bootstrap.js │ ├── bootstrap.js.map │ ├── bootstrap.min.js │ └── bootstrap.min.js.map ├── 3-authentication ├── README.md └── images │ ├── container_app.png │ ├── container_app_env.png │ ├── container_auth.png │ ├── ep3_thumb_yt_small.jpg │ ├── exp_180_days.png │ ├── login.png │ ├── permission-request.png │ └── provider-select.png ├── 3-opt-fine-grained-auth ├── README.md ├── images │ ├── after-login.png │ ├── before-login.png │ └── permissions.png └── sample │ ├── .dockerignore │ ├── Dockerfile.store │ ├── azure.yaml │ ├── eShopLite.sln │ ├── infra │ ├── abbreviations.json │ ├── bicepconfig.json │ ├── main.bicep │ ├── main.parameters.json │ ├── modules │ │ ├── app-registration.bicep │ │ ├── containerapps-authconfigs.bicep │ │ ├── fetch-container-image.bicep │ │ └── role-assignment.bicep │ └── resources.bicep │ └── src │ └── eShopLite.Store │ ├── ApiClients │ ├── ProductApiClient.cs │ └── StoreInfoApiClient.cs │ ├── Components │ ├── App.razor │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Error.razor │ │ ├── Home.razor │ │ ├── Products.razor │ │ └── Stores.razor │ ├── Routes.razor │ └── _Imports.razor │ ├── DataEntities │ ├── Product.cs │ └── StoreInfo.cs │ ├── Endpoints │ ├── ProductEndpoints.cs │ └── StoreInfoEndpoints.cs │ ├── Extensions │ ├── ProductDbContextExtensions.cs │ └── StoreInfoDbContextExtensions.cs │ ├── Handlers │ ├── EasyAuthAuthenticationBuilderExtensions.cs │ ├── EasyAuthAuthenticationHandler.cs │ ├── EasyAuthAuthenticationOptions.cs │ ├── MsClientPrincipal.cs │ └── MsClientPrincipalClaim.cs │ ├── Models │ └── ClientPrincipal.cs │ ├── ProductData │ ├── DbInitializer.cs │ └── ProductDbContext.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ └── AuthenticationService.cs │ ├── StoreInfoData │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ ├── app.css │ ├── favicon.png │ ├── images │ ├── product1.png │ ├── product2.png │ ├── product3.png │ ├── product4.png │ ├── product5.png │ ├── product6.png │ ├── product7.png │ ├── product8.png │ └── product9.png │ └── lib │ └── bootstrap │ └── dist │ ├── css │ ├── bootstrap-grid.css │ ├── bootstrap-grid.css.map │ ├── bootstrap-grid.min.css │ ├── bootstrap-grid.min.css.map │ ├── bootstrap-grid.rtl.css │ ├── bootstrap-grid.rtl.css.map │ ├── bootstrap-grid.rtl.min.css │ ├── bootstrap-grid.rtl.min.css.map │ ├── bootstrap-reboot.css │ ├── bootstrap-reboot.css.map │ ├── bootstrap-reboot.min.css │ ├── bootstrap-reboot.min.css.map │ ├── bootstrap-reboot.rtl.css │ ├── bootstrap-reboot.rtl.css.map │ ├── bootstrap-reboot.rtl.min.css │ ├── bootstrap-reboot.rtl.min.css.map │ ├── bootstrap-utilities.css │ ├── bootstrap-utilities.css.map │ ├── bootstrap-utilities.min.css │ ├── bootstrap-utilities.min.css.map │ ├── bootstrap-utilities.rtl.css │ ├── bootstrap-utilities.rtl.css.map │ ├── bootstrap-utilities.rtl.min.css │ ├── bootstrap-utilities.rtl.min.css.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ ├── bootstrap.rtl.css │ ├── bootstrap.rtl.css.map │ ├── bootstrap.rtl.min.css │ └── bootstrap.rtl.min.css.map │ └── js │ ├── bootstrap.bundle.js │ ├── bootstrap.bundle.js.map │ ├── bootstrap.bundle.min.js │ ├── bootstrap.bundle.min.js.map │ ├── bootstrap.esm.js │ ├── bootstrap.esm.js.map │ ├── bootstrap.esm.min.js │ ├── bootstrap.esm.min.js.map │ ├── bootstrap.js │ ├── bootstrap.js.map │ ├── bootstrap.min.js │ └── bootstrap.min.js.map ├── 4-microservices ├── README.md ├── images │ ├── app-running-3-term.png │ ├── container-apps-in-cae.png │ ├── ep4_thumb_yt_small.jpg │ └── successful-deploy.png └── sample │ ├── .gitignore │ ├── .vscode │ └── launch.json │ ├── Dockerfile.products │ ├── Dockerfile.store │ ├── Dockerfile.storeinfo │ ├── eShopLite.sln │ └── src │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ ├── WeatherForecast.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── 5-cicd ├── README.md ├── images │ ├── ep5_thumb_yt_small.jpg │ └── pipeline-config.png └── sample │ ├── .gitignore │ ├── Dockerfile.products │ ├── Dockerfile.store │ ├── Dockerfile.storeinfo │ ├── azure.yaml │ ├── eShopLite.sln │ ├── infra │ ├── abbreviations.json │ ├── main.bicep │ ├── main.parameters.json │ ├── modules │ │ └── fetch-container-image.bicep │ └── resources.bicep │ └── src │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── 6-cost-optimization ├── README.md ├── images │ └── ep6_thumb_yt_small.jpg └── sample │ ├── .gitignore │ ├── Dockerfile.products │ ├── Dockerfile.store │ ├── Dockerfile.storeinfo │ ├── azure.yaml │ ├── eShopLite.sln │ ├── infra │ ├── abbreviations.json │ ├── main.bicep │ ├── main.parameters.json │ ├── modules │ │ └── fetch-container-image.bicep │ └── resources.bicep │ └── src │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── 7-monitoring ├── README.md ├── images │ ├── alert_list.png │ ├── dashboard.png │ └── ep7_thumb_yt_small.jpg └── sample │ ├── .gitignore │ ├── Dockerfile.products │ ├── Dockerfile.store │ ├── Dockerfile.storeinfo │ ├── azure.yaml │ ├── docker-compose.yml │ ├── eShopLite.sln │ ├── infra │ ├── abbreviations.json │ ├── main.bicep │ ├── main.parameters.json │ ├── modules │ │ └── fetch-container-image.bicep │ └── resources.bicep │ └── src │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── 8-aspire ├── README.md ├── images │ ├── 8-aspire-01.png │ ├── 8-aspire-02.png │ ├── 8-aspire-03.png │ ├── 8-aspire-04.png │ └── ep8_thumb_yt_small.jpg └── sample │ ├── azure.yaml │ ├── eShopLite.sln │ └── src │ ├── eShopLite.AppHost │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ └── eShopLite.AppHost.csproj │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ ├── WeatherForecast.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.ServiceDefaults │ ├── Extensions.cs │ └── eShopLite.ServiceDefaults.csproj │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── 8-opt-aspire-integration ├── README.md ├── images │ ├── 8-opt-aspire-integration-01.png │ ├── 8-opt-aspire-integration-02.png │ ├── 8-opt-aspire-integration-03.png │ └── 8-opt-aspire-integration-04.png └── sample │ ├── eShopLite.sln │ └── src │ ├── eShopLite.DataEntities │ ├── Product.cs │ ├── StoreInfo.cs │ ├── WeatherForecast.cs │ └── eShopLite.DataEntities.csproj │ ├── eShopLite.Products │ ├── .config │ │ └── dotnet-tools.json │ ├── Data │ │ ├── DbInitializer.cs │ │ └── ProductDbContext.cs │ ├── Endpoints │ │ └── ProductEndpoints.cs │ ├── Extensions │ │ └── ProductDbContextExtensions.cs │ ├── Products.http │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Products.csproj │ └── wwwroot │ │ └── images │ │ ├── product1.png │ │ ├── product2.png │ │ ├── product3.png │ │ ├── product4.png │ │ ├── product5.png │ │ ├── product6.png │ │ ├── product7.png │ │ ├── product8.png │ │ └── product9.png │ ├── eShopLite.Store │ ├── ApiClients │ │ ├── ProductApiClient.cs │ │ └── StoreInfoApiClient.cs │ ├── Components │ │ ├── App.razor │ │ ├── Layout │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ └── NavMenu.razor.css │ │ ├── Pages │ │ │ ├── Home.razor │ │ │ ├── Products.razor │ │ │ └── Stores.razor │ │ ├── Routes.razor │ │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.Store.csproj │ └── wwwroot │ │ ├── app.css │ │ ├── bootstrap │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── favicon.png │ └── eShopLite.StoreInfo │ ├── Data │ ├── DbInitializer.cs │ └── StoreInfoDbContext.cs │ ├── Endpoints │ └── StoreInfoEndpoints.cs │ ├── Extensions │ └── StoreInfoDbContextExtensions.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── eShopLite.StoreInfo.csproj │ └── eShopLite.StoreInfo.http ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── global.json ├── images └── pl_thumb_yt_small.jpg └── scripts └── kill-ports.sh /.devcontainer/on-create.sh: -------------------------------------------------------------------------------- 1 | sudo apt-get update && \ 2 | sudo apt upgrade -y && \ 3 | sudo apt-get install -y dos2unix libsecret-1-0 xdg-utils && \ 4 | sudo apt clean -y && \ 5 | sudo rm -rf /var/lib/apt/lists/* 6 | 7 | echo Update .NET workloads 8 | dotnet workload update --from-previous-sdk 9 | 10 | echo Install .NET dev certs 11 | dotnet dev-certs https --trust 12 | 13 | echo Install Aspire 9 templates 14 | dotnet new install Aspire.ProjectTemplates 15 | 16 | echo Done! 17 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/bin 15 | **/charts 16 | **/docker-compose* 17 | **/compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md 26 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.sh text eol=lf 5 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /1-intro/images/ep1_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/1-intro/images/ep1_thumb_yt_small.jpg -------------------------------------------------------------------------------- /2-monolith-on-aca/images/ep2_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/images/ep2_thumb_yt_small.jpg -------------------------------------------------------------------------------- /2-monolith-on-aca/images/local-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/images/local-app.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/.dockerignore: -------------------------------------------------------------------------------- 1 | # Include any files or directories that you don't want to be copied to your 2 | # container here (e.g., local build artifacts, temporary files, etc.). 3 | # 4 | # For more help, visit the .dockerignore file reference guide at 5 | # https://docs.docker.com/go/build-context-dockerignore/ 6 | 7 | **/.DS_Store 8 | **/.classpath 9 | **/.dockerignore 10 | **/.env 11 | **/.git 12 | **/.gitignore 13 | **/.project 14 | **/.settings 15 | **/.toolstarget 16 | **/.vs 17 | **/.vscode 18 | **/*.*proj.user 19 | **/*.dbmdl 20 | **/*.jfm 21 | **/bin 22 | **/charts 23 | **/docker-compose* 24 | **/compose.y*ml 25 | **/Dockerfile* 26 | **/node_modules 27 | **/npm-debug.log 28 | **/obj 29 | **/secrets.dev.yaml 30 | **/values.dev.yaml 31 | LICENSE 32 | README.md 33 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | 7 | WORKDIR /source/eShopLite.Store 8 | 9 | RUN dotnet publish -c Release -o /app 10 | 11 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 12 | 13 | WORKDIR /app 14 | 15 | COPY --from=build /app . 16 | 17 | RUN chown $APP_UID /app 18 | 19 | USER $APP_UID 20 | 21 | RUN touch /app/Database.db 22 | 23 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 24 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.ProductData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateProductDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/ProductData/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Store.ProductData; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "https": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "https://localhost:7000;http://localhost:8080", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "http": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "http://localhost:8080", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/StoreInfoData/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using eShopLite.Store.DataEntities; 3 | 4 | namespace eShopLite.Store.StoreInfoData; 5 | 6 | public class StoreInfoDbContext : DbContext 7 | { 8 | public StoreInfoDbContext(DbContextOptions options) 9 | : base(options) 10 | { 11 | } 12 | 13 | public DbSet Store { get; set; } = default!; 14 | } 15 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db", 13 | "StoreInfoContext": "Data Source=StoreInfo.db" 14 | } 15 | } -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Store 10 | eShopLite.Store 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product1.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product2.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product3.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product4.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product5.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product6.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product7.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product8.png -------------------------------------------------------------------------------- /2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/2-monolith-on-aca/sample/src/eShopLite.Store/wwwroot/images/product9.png -------------------------------------------------------------------------------- /3-authentication/images/container_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/container_app.png -------------------------------------------------------------------------------- /3-authentication/images/container_app_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/container_app_env.png -------------------------------------------------------------------------------- /3-authentication/images/container_auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/container_auth.png -------------------------------------------------------------------------------- /3-authentication/images/ep3_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/ep3_thumb_yt_small.jpg -------------------------------------------------------------------------------- /3-authentication/images/exp_180_days.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/exp_180_days.png -------------------------------------------------------------------------------- /3-authentication/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/login.png -------------------------------------------------------------------------------- /3-authentication/images/permission-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/permission-request.png -------------------------------------------------------------------------------- /3-authentication/images/provider-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-authentication/images/provider-select.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/images/after-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/images/after-login.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/images/before-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/images/before-login.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/images/permissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/images/permissions.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/.dockerignore: -------------------------------------------------------------------------------- 1 | # Include any files or directories that you don't want to be copied to your 2 | # container here (e.g., local build artifacts, temporary files, etc.). 3 | # 4 | # For more help, visit the .dockerignore file reference guide at 5 | # https://docs.docker.com/go/build-context-dockerignore/ 6 | 7 | **/.DS_Store 8 | **/.classpath 9 | **/.dockerignore 10 | **/.env 11 | **/.git 12 | **/.gitignore 13 | **/.project 14 | **/.settings 15 | **/.toolstarget 16 | **/.vs 17 | **/.vscode 18 | **/*.*proj.user 19 | **/*.dbmdl 20 | **/*.jfm 21 | **/bin 22 | **/charts 23 | **/docker-compose* 24 | **/compose.y*ml 25 | **/Dockerfile* 26 | **/node_modules 27 | **/npm-debug.log 28 | **/obj 29 | **/secrets.dev.yaml 30 | **/values.dev.yaml 31 | LICENSE 32 | README.md 33 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | 7 | WORKDIR /source/eShopLite.Store 8 | 9 | RUN dotnet publish -c Release -o /app 10 | 11 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 12 | 13 | WORKDIR /app 14 | 15 | COPY --from=build /app . 16 | 17 | RUN chown $APP_UID /app 18 | 19 | USER $APP_UID 20 | 21 | RUN touch /app/Database.db 22 | 23 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 24 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/azure.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json 2 | 3 | name: 3-opt-fine-grained-auth 4 | 5 | metadata: 6 | template: azd-init@1.11.0 7 | 8 | services: 9 | eshoplite-store: 10 | project: src/eShopLite.Store 11 | host: containerapp 12 | language: dotnet 13 | docker: 14 | path: ../../Dockerfile.store 15 | context: ../../ 16 | remoteBuild: true 17 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/infra/bicepconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "experimentalFeaturesEnabled": { 3 | "extensibility": true 4 | }, 5 | "extensions": { 6 | "microsoftGraphV1": "br:mcr.microsoft.com/bicep/extensions/microsoftgraph/v1.0:0.1.8-preview" 7 | } 8 | } -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/infra/modules/fetch-container-image.bicep: -------------------------------------------------------------------------------- 1 | param exists bool 2 | param name string 3 | 4 | resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) { 5 | name: name 6 | } 7 | 8 | output containers array = exists ? existingApp.properties.template.containers : [] 9 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Hello, world!

6 | 7 | Welcome to your new app. 8 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.ProductData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateProductDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Handlers/EasyAuthAuthenticationBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication; 2 | 3 | namespace eShopLite.Store.Handlers; 4 | 5 | public static class EasyAuthAuthenticationBuilderExtensions 6 | { 7 | public static AuthenticationBuilder AddAzureEasyAuthHandler(this AuthenticationBuilder builder, Action? configure = null) 8 | { 9 | if (configure == null) 10 | { 11 | configure = o => { }; 12 | } 13 | 14 | return builder.AddScheme( 15 | EasyAuthAuthenticationHandler.EASY_AUTH_SCHEME_NAME, 16 | EasyAuthAuthenticationHandler.EASY_AUTH_SCHEME_NAME, 17 | configure); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Handlers/EasyAuthAuthenticationOptions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authentication; 2 | 3 | namespace eShopLite.Store.Handlers; 4 | 5 | public class EasyAuthAuthenticationOptions : AuthenticationSchemeOptions 6 | { 7 | public EasyAuthAuthenticationOptions() 8 | { 9 | Events = new object(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Handlers/MsClientPrincipalClaim.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.Handlers; 4 | 5 | public class MsClientPrincipalClaim 6 | { 7 | [JsonPropertyName("typ")] 8 | public string? Type { get; set; } 9 | 10 | [JsonPropertyName("val")] 11 | public string? Value { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Models/ClientPrincipal.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.Models; 4 | 5 | public class ClientPrincipal 6 | { 7 | [JsonPropertyName("auth_type")] 8 | public string? AuthType { get; set; } 9 | 10 | [JsonPropertyName("claims")] 11 | public List Claims { get; set; } = new(); 12 | 13 | [JsonPropertyName("name_typ")] 14 | public string? NameType { get; set; } 15 | 16 | [JsonPropertyName("role_typ")] 17 | public string? RoleType { get; set; } 18 | } 19 | 20 | public class PrincipalClaim 21 | { 22 | [JsonPropertyName("typ")] 23 | public string? Type { get; set; } 24 | 25 | [JsonPropertyName("val")] 26 | public string? Value { get; set; } 27 | } 28 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/ProductData/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Store.ProductData; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "https": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "https://localhost:7000;http://localhost:8080", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "http": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "http://localhost:8080", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/StoreInfoData/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Store.StoreInfoData; 6 | 7 | public class StoreInfoDbContext : DbContext 8 | { 9 | public StoreInfoDbContext(DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Store { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Database.db", 13 | "StoreInfoContext": "Data Source=StoreInfo.db" 14 | } 15 | } -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Store 10 | eShopLite.Store 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product1.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product2.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product3.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product4.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product5.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product6.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product7.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product8.png -------------------------------------------------------------------------------- /3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/3-opt-fine-grained-auth/sample/src/eShopLite.Store/wwwroot/images/product9.png -------------------------------------------------------------------------------- /4-microservices/images/app-running-3-term.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/images/app-running-3-term.png -------------------------------------------------------------------------------- /4-microservices/images/container-apps-in-cae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/images/container-apps-in-cae.png -------------------------------------------------------------------------------- /4-microservices/images/ep4_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/images/ep4_thumb_yt_small.jpg -------------------------------------------------------------------------------- /4-microservices/images/successful-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/images/successful-deploy.png -------------------------------------------------------------------------------- /4-microservices/sample/.gitignore: -------------------------------------------------------------------------------- 1 | .azure 2 | -------------------------------------------------------------------------------- /4-microservices/sample/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "compounds": [ 4 | { 5 | "name": "Run all", 6 | "configurations": [ 7 | "Run api-product", 8 | "Run api-weather", 9 | "Run web" 10 | ] 11 | } 12 | ], 13 | "configurations": [ 14 | { 15 | "name": "Run api-product", 16 | "type": "dotnet", 17 | "request": "launch", 18 | "projectPath": "${workspaceFolder}/src/eShopLite.Products/eShopLite.Products.csproj" 19 | }, 20 | { 21 | "name": "Run api-weather", 22 | "type": "dotnet", 23 | "request": "launch", 24 | "projectPath": "${workspaceFolder}/src/eShopLite.Weather/eShopLite.Weather.csproj" 25 | }, 26 | { 27 | "name": "Run web", 28 | "type": "dotnet", 29 | "request": "launch", 30 | "projectPath": "${workspaceFolder}/src/eShopLite.Store/eShopLite.Store.csproj" 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /4-microservices/sample/Dockerfile.products: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Products /source/eShopLite.Products 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Products 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/Products.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.Products.dll"] 25 | -------------------------------------------------------------------------------- /4-microservices/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Store 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | USER $APP_UID 19 | 20 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 21 | -------------------------------------------------------------------------------- /4-microservices/sample/Dockerfile.storeinfo: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.StoreInfo /source/eShopLite.StoreInfo 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.StoreInfo 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/StoreInfo.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.StoreInfo.dll"] 25 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.DataEntities/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace eShopLite.DataEntities; 2 | 3 | public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 4 | { 5 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 6 | } 7 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*", 11 | 12 | "ProductsApi": "http://localhost:5228", 13 | "StoreInfoApi": "http://localhost:5012" 14 | } 15 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/4-microservices/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | 16 | builder.Services.AddDbContext(options => 17 | { 18 | var connectionString = builder.Configuration.GetConnectionString("StoreInfoContext") ?? throw new InvalidOperationException("Connection string 'StoreInfoContext' not found."); 19 | options.UseSqlite(connectionString); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | // Configure the HTTP request pipeline. 25 | if (app.Environment.IsDevelopment()) 26 | { 27 | app.MapOpenApi(); 28 | } 29 | 30 | app.UseHttpsRedirection(); 31 | app.MapStoreInfoEndpoints(); 32 | app.CreateStoreInfoDbIfNotExists(); 33 | 34 | app.Run(); 35 | 36 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /4-microservices/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /5-cicd/images/ep5_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/images/ep5_thumb_yt_small.jpg -------------------------------------------------------------------------------- /5-cicd/images/pipeline-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/images/pipeline-config.png -------------------------------------------------------------------------------- /5-cicd/sample/.gitignore: -------------------------------------------------------------------------------- 1 | .azure 2 | -------------------------------------------------------------------------------- /5-cicd/sample/Dockerfile.products: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Products /source/eShopLite.Products 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Products 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/Products.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.Products.dll"] 25 | -------------------------------------------------------------------------------- /5-cicd/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Store 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | USER $APP_UID 19 | 20 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 21 | -------------------------------------------------------------------------------- /5-cicd/sample/Dockerfile.storeinfo: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.StoreInfo /source/eShopLite.StoreInfo 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.StoreInfo 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/StoreInfo.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.StoreInfo.dll"] 25 | -------------------------------------------------------------------------------- /5-cicd/sample/azure.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json 2 | 3 | name: sample 4 | metadata: 5 | template: azd-init@1.12.0 6 | services: 7 | eshoplite-products: 8 | project: src/eShopLite.Products 9 | host: containerapp 10 | language: dotnet 11 | docker: 12 | path: ../../Dockerfile.products 13 | context: ../../ 14 | remoteBuild: true 15 | eshoplite-store: 16 | project: src/eShopLite.Store 17 | host: containerapp 18 | language: dotnet 19 | docker: 20 | path: ../../Dockerfile.store 21 | context: ../../ 22 | remoteBuild: true 23 | eshoplite-storeinfo: 24 | project: src/eShopLite.StoreInfo 25 | host: containerapp 26 | language: dotnet 27 | docker: 28 | path: ../../Dockerfile.storeinfo 29 | context: ../../ 30 | remoteBuild: true 31 | -------------------------------------------------------------------------------- /5-cicd/sample/infra/modules/fetch-container-image.bicep: -------------------------------------------------------------------------------- 1 | param exists bool 2 | param name string 3 | 4 | resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) { 5 | name: name 6 | } 7 | 8 | output containers array = exists ? existingApp.properties.template.containers : [] 9 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | using eShopLite.Products.Endpoints; 3 | using eShopLite.Products.Extensions; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Add OpenAPI services 13 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 14 | builder.Services.AddOpenApi(); 15 | 16 | // Add database context 17 | builder.Services.AddDbContext(options => 18 | { 19 | var connectionString = builder.Configuration.GetConnectionString("ProductsContext") ?? throw new InvalidOperationException("Connection string 'ProductsContext' not found."); 20 | options.UseSqlite(connectionString); 21 | }); 22 | 23 | var app = builder.Build(); 24 | 25 | // Configure the HTTP request pipeline. 26 | if (app.Environment.IsDevelopment()) 27 | { 28 | app.MapOpenApi(); 29 | } 30 | 31 | app.UseHttpsRedirection(); 32 | 33 | app.UseStaticFiles(); 34 | 35 | app.MapProductEndpoints(); 36 | 37 | app.CreateDbIfNotExists(); 38 | 39 | app.Run(); 40 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*", 11 | 12 | "ProductsApi": "http://localhost:5228", 13 | "StoreInfoApi": "http://localhost:5012" 14 | } 15 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/5-cicd/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | 16 | builder.Services.AddDbContext(options => 17 | { 18 | var connectionString = builder.Configuration.GetConnectionString("StoreInfoContext") ?? throw new InvalidOperationException("Connection string 'StoreInfoContext' not found."); 19 | options.UseSqlite(connectionString); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | // Configure the HTTP request pipeline. 25 | if (app.Environment.IsDevelopment()) 26 | { 27 | app.MapOpenApi(); 28 | } 29 | 30 | app.UseHttpsRedirection(); 31 | app.MapStoreInfoEndpoints(); 32 | app.CreateStoreInfoDbIfNotExists(); 33 | 34 | app.Run(); 35 | 36 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /5-cicd/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /6-cost-optimization/images/ep6_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/images/ep6_thumb_yt_small.jpg -------------------------------------------------------------------------------- /6-cost-optimization/sample/.gitignore: -------------------------------------------------------------------------------- 1 | .azure 2 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/Dockerfile.products: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Products /source/eShopLite.Products 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Products 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/Products.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.Products.dll"] 25 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Store 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | USER $APP_UID 19 | 20 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 21 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/Dockerfile.storeinfo: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.StoreInfo /source/eShopLite.StoreInfo 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.StoreInfo 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/StoreInfo.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.StoreInfo.dll"] 25 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/azure.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json 2 | 3 | name: sample 4 | metadata: 5 | template: azd-init@1.12.0 6 | services: 7 | eshoplite-products: 8 | project: src/eShopLite.Products 9 | host: containerapp 10 | language: dotnet 11 | docker: 12 | path: ../../Dockerfile.products 13 | context: ../../ 14 | remoteBuild: true 15 | eshoplite-store: 16 | project: src/eShopLite.Store 17 | host: containerapp 18 | language: dotnet 19 | docker: 20 | path: ../../Dockerfile.store 21 | context: ../../ 22 | remoteBuild: true 23 | eshoplite-storeinfo: 24 | project: src/eShopLite.StoreInfo 25 | host: containerapp 26 | language: dotnet 27 | docker: 28 | path: ../../Dockerfile.storeinfo 29 | context: ../../ 30 | remoteBuild: true 31 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/infra/modules/fetch-container-image.bicep: -------------------------------------------------------------------------------- 1 | param exists bool 2 | param name string 3 | 4 | resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) { 5 | name: name 6 | } 7 | 8 | output containers array = exists ? existingApp.properties.template.containers : [] 9 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*", 11 | 12 | "ProductsApi": "http://localhost:5228", 13 | "StoreInfoApi": "http://localhost:5012" 14 | } 15 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/6-cost-optimization/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | 16 | builder.Services.AddDbContext(options => 17 | { 18 | var connectionString = builder.Configuration.GetConnectionString("StoreInfoContext") ?? throw new InvalidOperationException("Connection string 'StoreInfoContext' not found."); 19 | options.UseSqlite(connectionString); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | // Configure the HTTP request pipeline. 25 | if (app.Environment.IsDevelopment()) 26 | { 27 | app.MapOpenApi(); 28 | } 29 | 30 | app.UseHttpsRedirection(); 31 | app.MapStoreInfoEndpoints(); 32 | app.CreateStoreInfoDbIfNotExists(); 33 | 34 | app.Run(); 35 | 36 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /6-cost-optimization/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /7-monitoring/images/alert_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/images/alert_list.png -------------------------------------------------------------------------------- /7-monitoring/images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/images/dashboard.png -------------------------------------------------------------------------------- /7-monitoring/images/ep7_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/images/ep7_thumb_yt_small.jpg -------------------------------------------------------------------------------- /7-monitoring/sample/.gitignore: -------------------------------------------------------------------------------- 1 | .azure 2 | -------------------------------------------------------------------------------- /7-monitoring/sample/Dockerfile.products: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Products /source/eShopLite.Products 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Products 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/Products.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.Products.dll"] 25 | -------------------------------------------------------------------------------- /7-monitoring/sample/Dockerfile.store: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.Store /source/eShopLite.Store 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.Store 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | USER $APP_UID 19 | 20 | ENTRYPOINT ["dotnet", "eShopLite.Store.dll"] 21 | -------------------------------------------------------------------------------- /7-monitoring/sample/Dockerfile.storeinfo: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build 4 | 5 | COPY ./src/eShopLite.StoreInfo /source/eShopLite.StoreInfo 6 | COPY ./src/eShopLite.DataEntities /source/eShopLite.DataEntities 7 | 8 | WORKDIR /source/eShopLite.StoreInfo 9 | 10 | RUN dotnet publish -c Release -o /app 11 | 12 | FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final 13 | 14 | WORKDIR /app 15 | 16 | COPY --from=build /app . 17 | 18 | RUN chown $APP_UID /app 19 | 20 | USER $APP_UID 21 | 22 | RUN touch /app/StoreInfo.db 23 | 24 | ENTRYPOINT ["dotnet", "eShopLite.StoreInfo.dll"] 25 | -------------------------------------------------------------------------------- /7-monitoring/sample/azure.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json 2 | 3 | name: sample 4 | metadata: 5 | template: azd-init@1.12.0 6 | services: 7 | eshoplite-products: 8 | project: src/eShopLite.Products 9 | host: containerapp 10 | language: dotnet 11 | docker: 12 | path: ../../Dockerfile.products 13 | context: ../../ 14 | remoteBuild: true 15 | eshoplite-store: 16 | project: src/eShopLite.Store 17 | host: containerapp 18 | language: dotnet 19 | docker: 20 | path: ../../Dockerfile.store 21 | context: ../../ 22 | remoteBuild: true 23 | eshoplite-storeinfo: 24 | project: src/eShopLite.StoreInfo 25 | host: containerapp 26 | language: dotnet 27 | docker: 28 | path: ../../Dockerfile.storeinfo 29 | context: ../../ 30 | remoteBuild: true 31 | -------------------------------------------------------------------------------- /7-monitoring/sample/docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | name: eshoplite 3 | services: 4 | 5 | eshoplite-products: 6 | image: eshoplite-products 7 | container_name: eshoplite-products 8 | hostname: products 9 | build: 10 | context: . 11 | dockerfile: ./Dockerfile.products 12 | networks: 13 | - eshop-net 14 | 15 | eshoplite-storeinfo: 16 | image: eshoplite-storeinfo 17 | container_name: eshoplite-storeinfo 18 | hostname: storeinfo 19 | build: 20 | context: . 21 | dockerfile: ./Dockerfile.storeinfo 22 | networks: 23 | - eshop-net 24 | 25 | eshoplite-store: 26 | image: eshoplite-store 27 | container_name: eshoplite-store 28 | hostname: store 29 | build: 30 | context: . 31 | dockerfile: ./Dockerfile.store 32 | ports: 33 | - 5158:8080 34 | links: 35 | - eshoplite-products:products 36 | - eshoplite-storeinfo:storeinfo 37 | depends_on: 38 | - eshoplite-products 39 | - eshoplite-storeinfo 40 | networks: 41 | - eshop-net 42 | 43 | networks: 44 | eshop-net: 45 | -------------------------------------------------------------------------------- /7-monitoring/sample/infra/modules/fetch-container-image.bicep: -------------------------------------------------------------------------------- 1 | param exists bool 2 | param name string 3 | 4 | resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) { 5 | name: name 6 | } 7 | 8 | output containers array = exists ? existingApp.properties.template.containers : [] 9 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | 9 |
10 | Note: This version of the demo has been tampered with by adding delays and errors to simulate a real-life application and provide information for monitoring. 11 |
12 | 13 | 25 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*", 11 | 12 | "ProductsApi": "http://localhost:5228", 13 | "StoreInfoApi": "http://localhost:5012" 14 | } 15 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/7-monitoring/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | 16 | builder.Services.AddDbContext(options => 17 | { 18 | var connectionString = builder.Configuration.GetConnectionString("StoreInfoContext") ?? throw new InvalidOperationException("Connection string 'StoreInfoContext' not found."); 19 | options.UseSqlite(connectionString); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | // Configure the HTTP request pipeline. 25 | if (app.Environment.IsDevelopment()) 26 | { 27 | app.MapOpenApi(); 28 | } 29 | 30 | app.UseHttpsRedirection(); 31 | app.MapStoreInfoEndpoints(); 32 | app.CreateStoreInfoDbIfNotExists(); 33 | 34 | app.Run(); 35 | 36 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 1b0ac4f8-53ba-4db3-9832-9736558e418e 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /7-monitoring/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /8-aspire/images/8-aspire-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/images/8-aspire-01.png -------------------------------------------------------------------------------- /8-aspire/images/8-aspire-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/images/8-aspire-02.png -------------------------------------------------------------------------------- /8-aspire/images/8-aspire-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/images/8-aspire-03.png -------------------------------------------------------------------------------- /8-aspire/images/8-aspire-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/images/8-aspire-04.png -------------------------------------------------------------------------------- /8-aspire/images/ep8_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/images/ep8_thumb_yt_small.jpg -------------------------------------------------------------------------------- /8-aspire/sample/azure.yaml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json 2 | 3 | name: 8-aspire 4 | services: 5 | app: 6 | language: dotnet 7 | project: ./src/eShopLite.AppHost/eShopLite.AppHost.csproj 8 | host: containerapp 9 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.AppHost/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = DistributedApplication.CreateBuilder(args); 2 | 3 | var pg = builder.AddPostgres("pg") 4 | .WithPgAdmin(); 5 | var productsdb = pg.AddDatabase("productsdb"); 6 | var storeinfodb = pg.AddDatabase("storeinfodb"); 7 | 8 | var products = builder.AddProject("products") 9 | .WithReference(productsdb) 10 | .WaitFor(productsdb); 11 | 12 | var storeinfo = builder.AddProject("storeinfo") 13 | .WithReference(storeinfodb) 14 | .WaitFor(storeinfodb); 15 | 16 | var store = builder.AddProject("store") 17 | .WithExternalHttpEndpoints() 18 | .WithReference(products) 19 | .WithReference(storeinfo) 20 | .WaitFor(products) 21 | .WaitFor(storeinfo); 22 | 23 | builder.Build().Run(); 24 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.AppHost/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.AppHost/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning", 6 | "Aspire.Hosting.Dcp": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.AppHost/eShopLite.AppHost.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Exe 7 | net9.0 8 | enable 9 | enable 10 | true 11 | a764f85f-8cd1-484c-8dd4-902c0a326550 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.DataEntities/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace eShopLite.DataEntities; 2 | 3 | public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 4 | { 5 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 6 | } 7 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | using eShopLite.Products.Endpoints; 3 | using eShopLite.Products.Extensions; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | builder.AddServiceDefaults(); 10 | 11 | // Add services to the container. 12 | builder.Services.AddProblemDetails(); 13 | 14 | // Add OpenAPI services 15 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 16 | builder.Services.AddOpenApi(); 17 | 18 | // Add database context 19 | builder.AddNpgsqlDbContext("productsdb"); 20 | 21 | var app = builder.Build(); 22 | 23 | app.MapDefaultEndpoints(); 24 | 25 | // Configure the HTTP request pipeline. 26 | if (app.Environment.IsDevelopment()) 27 | { 28 | app.MapOpenApi(); 29 | } 30 | 31 | app.UseHttpsRedirection(); 32 | 33 | app.UseStaticFiles(); 34 | 35 | app.MapProductEndpoints(); 36 | 37 | app.CreateDbIfNotExists(); 38 | 39 | app.Run(); 40 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.ServiceDefaults/eShopLite.ServiceDefaults.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*" 11 | } 12 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-aspire/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | var builder = WebApplication.CreateBuilder(args); 6 | 7 | builder.AddServiceDefaults(); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | builder.AddNpgsqlDbContext("storeinfodb"); 16 | 17 | var app = builder.Build(); 18 | 19 | app.MapDefaultEndpoints(); 20 | 21 | // Configure the HTTP request pipeline. 22 | if (app.Environment.IsDevelopment()) 23 | { 24 | app.MapOpenApi(); 25 | } 26 | 27 | app.UseHttpsRedirection(); 28 | app.MapStoreInfoEndpoints(); 29 | app.CreateStoreInfoDbIfNotExists(); 30 | 31 | app.Run(); 32 | 33 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /8-aspire/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/images/8-opt-aspire-integration-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/images/8-opt-aspire-integration-01.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/images/8-opt-aspire-integration-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/images/8-opt-aspire-integration-02.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/images/8-opt-aspire-integration-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/images/8-opt-aspire-integration-03.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/images/8-opt-aspire-integration-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/images/8-opt-aspire-integration-04.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.DataEntities/Product.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.DataEntities; 4 | 5 | public class Product 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | 10 | [JsonPropertyName("name")] 11 | public string? Name { get; set; } 12 | 13 | [JsonPropertyName("description")] 14 | public string? Description { get; set; } 15 | 16 | [JsonPropertyName("price")] 17 | public decimal Price { get; set; } 18 | 19 | [JsonPropertyName("imageUrl")] 20 | public string? ImageUrl { get; set; } 21 | } 22 | 23 | 24 | [JsonSerializable(typeof(List))] 25 | public sealed partial class ProductSerializerContext : JsonSerializerContext 26 | { 27 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.DataEntities/StoreInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace eShopLite.Store.DataEntities; 4 | 5 | public class StoreInfo 6 | { 7 | [JsonPropertyName("id")] 8 | public int Id { get; set; } 9 | [JsonPropertyName("name")] 10 | public string? Name { get; set; } 11 | [JsonPropertyName("city")] 12 | public string? City { get; set; } 13 | [JsonPropertyName("state")] 14 | public string? State { get; set; } 15 | [JsonPropertyName("hours")] 16 | public string? Hours { get; set; } 17 | } 18 | 19 | [JsonSerializable(typeof(List))] 20 | public sealed partial class StoreInfoSerializerContext : JsonSerializerContext 21 | { 22 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.DataEntities/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | namespace eShopLite.DataEntities; 2 | 3 | public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) 4 | { 5 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 6 | } 7 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.DataEntities/eShopLite.DataEntities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.DataEntities 9 | eShopLite.DataEntities 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "7.0.10", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/Data/ProductDbContext.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace eShopLite.Products.Data; 6 | 7 | public class ProductDbContext : DbContext 8 | { 9 | public ProductDbContext (DbContextOptions options) 10 | : base(options) 11 | { 12 | } 13 | 14 | public DbSet Product { get; set; } = default!; 15 | } 16 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/Extensions/ProductDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Products.Data; 2 | 3 | namespace eShopLite.Products.Extensions; 4 | 5 | public static class ProductDbContextExtensions 6 | { 7 | public static void CreateDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/Products.http: -------------------------------------------------------------------------------- 1 | @HostAddress = http://localhost:5228 2 | 3 | GET {{HostAddress}}/api/products 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "launchUrl": "api/products", 9 | "applicationUrl": "http://localhost:5228", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": true, 18 | "launchUrl": "api/products", 19 | "applicationUrl": "https://localhost:7130;http://localhost:5228", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | 9 | "AllowedHosts": "*", 10 | 11 | "ConnectionStrings": { 12 | "ProductsContext": "Data Source=Products.db" 13 | } 14 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/eShopLite.Products.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | 9 | eShopLite.Products 10 | eShopLite.Products 11 | 12 | 1ffc2aab-f1e5-42be-906c-3461644e7786 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product1.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product2.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product3.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product4.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product5.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product6.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product7.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product8.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Products/wwwroot/images/product9.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/ApiClients/ProductApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class ProductApiClient(HttpClient http) 6 | { 7 | public async Task> GetProductsAsync(int maxItems = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? products = null; 10 | 11 | await foreach (var product in http.GetFromJsonAsAsyncEnumerable("/api/products", cancellationToken)) 12 | { 13 | if (products?.Count >= maxItems) 14 | { 15 | break; 16 | } 17 | if (product is not null) 18 | { 19 | products ??= []; 20 | products.Add(product); 21 | } 22 | } 23 | 24 | return products ?? []; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/ApiClients/StoreInfoApiClient.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.DataEntities; 2 | 3 | namespace eShopLite.Store.ApiClients; 4 | 5 | public class StoreInfoApiClient(HttpClient http) 6 | { 7 | public async Task> GetStoreInfoAsync(int maxStores = 10, CancellationToken cancellationToken = default) 8 | { 9 | List? storeInfo = null; 10 | 11 | await Task.Delay(2000); 12 | 13 | await foreach (var info in http.GetFromJsonAsAsyncEnumerable("/api/storeinfo", cancellationToken)) 14 | { 15 | if (storeInfo?.Count >= maxStores) 16 | { 17 | break; 18 | } 19 | if (info is not null) 20 | { 21 | storeInfo ??= []; 22 | storeInfo.Add(info); 23 | } 24 | } 25 | return storeInfo ?? []; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 | Home 4 | 5 |

Home

6 | 7 | Welcome to the best e-commerce platform in the world - eShopLite! 8 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using eShopLite.Store 10 | @using eShopLite.Store.Components 11 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "http://localhost:5158", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": true, 17 | "applicationUrl": "https://localhost:7085;http://localhost:5158", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft.AspNetCore": "Warning" 7 | } 8 | }, 9 | 10 | "AllowedHosts": "*", 11 | 12 | "ProductsApi": "http://localhost:5228", 13 | "StoreInfoApi": "http://localhost:5012" 14 | } 15 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/eShopLite.Store.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | eShopLite.Store 9 | eShopLite.Store 10 | d2c2ce8c-099f-41ba-9a87-5d5a0b860617 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.Store/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/8-opt-aspire-integration/sample/src/eShopLite.Store/wwwroot/favicon.png -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/Data/StoreInfoDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using eShopLite.Store.DataEntities; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace eShopLite.Store.StoreInfoData; 8 | 9 | public class StoreInfoDbContext : DbContext 10 | { 11 | public StoreInfoDbContext(DbContextOptions options) 12 | : base(options) 13 | { 14 | } 15 | 16 | public DbSet Store { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/Extensions/StoreInfoDbContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.StoreInfoData; 2 | 3 | namespace eShopLite.Store.Extensions; 4 | 5 | public static class StoreInfoDbContextExtensions 6 | { 7 | public static void CreateStoreInfoDbIfNotExists(this IHost host) 8 | { 9 | using var scope = host.Services.CreateScope(); 10 | var services = scope.ServiceProvider; 11 | var context = services.GetRequiredService(); 12 | context.Database.EnsureCreated(); 13 | DbInitializer.Initialize(context); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/Program.cs: -------------------------------------------------------------------------------- 1 | using eShopLite.Store.Endpoints; 2 | using eShopLite.Store.Extensions; 3 | using eShopLite.Store.StoreInfoData; 4 | 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | var builder = WebApplication.CreateBuilder(args); 8 | 9 | // Add services to the container. 10 | builder.Services.AddProblemDetails(); 11 | 12 | // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi 13 | builder.Services.AddOpenApi(); 14 | 15 | 16 | builder.Services.AddDbContext(options => 17 | { 18 | var connectionString = builder.Configuration.GetConnectionString("StoreInfoContext") ?? throw new InvalidOperationException("Connection string 'StoreInfoContext' not found."); 19 | options.UseSqlite(connectionString); 20 | }); 21 | 22 | var app = builder.Build(); 23 | 24 | // Configure the HTTP request pipeline. 25 | if (app.Environment.IsDevelopment()) 26 | { 27 | app.MapOpenApi(); 28 | } 29 | 30 | app.UseHttpsRedirection(); 31 | app.MapStoreInfoEndpoints(); 32 | app.CreateStoreInfoDbIfNotExists(); 33 | 34 | app.Run(); 35 | 36 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "launchUrl": "api/storeinfo", 9 | "applicationUrl": "http://localhost:5012", 10 | "environmentVariables": { 11 | "ASPNETCORE_ENVIRONMENT": "Development" 12 | } 13 | }, 14 | "https": { 15 | "commandName": "Project", 16 | "dotnetRunMessages": true, 17 | "launchBrowser": false, 18 | "launchUrl": "api/storeinfo", 19 | "applicationUrl": "https://localhost:7211;http://localhost:5012", 20 | "environmentVariables": { 21 | "ASPNETCORE_ENVIRONMENT": "Development" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*", 9 | "ConnectionStrings": { 10 | "StoreInfoContext": "Data Source=StoreInfo.db" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /8-opt-aspire-integration/sample/src/eShopLite.StoreInfo/eShopLite.StoreInfo.http: -------------------------------------------------------------------------------- 1 | @eShopLite.StoreInfo_HostAddress = http://localhost:5012 2 | 3 | GET {{eShopLite.StoreInfo_HostAddress}}/api/storeinfo 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog of .NET on Azure Container Apps for Beginners 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "allowPrerelease": false 4 | } 5 | } -------------------------------------------------------------------------------- /images/pl_thumb_yt_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/getting-started-dotnet-aca/66ecb2d8f44a3eecc14da30d085932c3b8a5a709/images/pl_thumb_yt_small.jpg -------------------------------------------------------------------------------- /scripts/kill-ports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Kill all processes listening on the specified ports 3 | 4 | ports=(3000 3030 3031 5000 5050 5051 7000 7070 7071 8080) 5 | 6 | echo "Killing processes listening on ports: ${ports[@]}" 7 | 8 | for port in "${ports[@]}"; 9 | do 10 | lsof -i :$port | grep LISTEN | awk '{print $2}' | xargs kill -9 11 | done 12 | 13 | # Run one more time just in case 14 | for port in "${ports[@]}"; 15 | do 16 | lsof -i :$port | grep LISTEN | awk '{print $2}' | xargs kill -9 17 | done 18 | --------------------------------------------------------------------------------