From 4dab255fc4e80dd7a244a149b41848d4585f9625 Mon Sep 17 00:00:00 2001
From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com>
Date: Fri, 14 Oct 2022 17:13:25 +0200
Subject: [PATCH] docs: Add persistence layer (MSSQL) to WeatherForecast
example
---
.gitattributes | 3 +-
examples/WeatherForecast/Packages.props | 18 ++++---
examples/WeatherForecast/WeatherForecast.sln | 6 +++
.../WeatherDataContext.cs | 37 ++++++++++++++
.../WeatherDataReadOnlyContext.cs | 37 ++++++++++++++
.../WeatherDataWriteOnlyContext.cs | 31 ++++++++++++
.../WeatherForecast.Contexts.csproj | 13 +++++
.../src/WeatherForecast.Entities/HasId.cs | 20 ++++++++
.../WeatherForecast.Entities/Temperature.cs | 42 ++++++++++------
.../WeatherForecast.Entities/WeatherData.cs | 22 +++++---
.../WeatherForecast.Entities.csproj | 2 +
.../WeatherDataReadOnlyRepository.cs | 2 +-
.../src/WeatherForecast/Program.cs | 22 ++++++--
.../WeatherForecast/WeatherForecast.csproj | 2 +
.../WeatherForecast.Test.csproj | 2 +-
.../WeatherForecastContainer.cs | 50 ++++++++++++++++---
16 files changed, 269 insertions(+), 40 deletions(-)
create mode 100644 examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataContext.cs
create mode 100644 examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataReadOnlyContext.cs
create mode 100644 examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataWriteOnlyContext.cs
create mode 100644 examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherForecast.Contexts.csproj
create mode 100644 examples/WeatherForecast/src/WeatherForecast.Entities/HasId.cs
diff --git a/.gitattributes b/.gitattributes
index 310176ed1..49ccf7597 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,8 +1,9 @@
# Autodetect text files
* text=auto
-# Definitively text files
+# Definitively text files
*.cs text
*.cake text
# Git lfs
+*.crt filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
diff --git a/examples/WeatherForecast/Packages.props b/examples/WeatherForecast/Packages.props
index cb0944b15..b646ff7e2 100644
--- a/examples/WeatherForecast/Packages.props
+++ b/examples/WeatherForecast/Packages.props
@@ -1,12 +1,16 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/WeatherForecast/WeatherForecast.sln b/examples/WeatherForecast/WeatherForecast.sln
index df836eedd..1f515a78d 100644
--- a/examples/WeatherForecast/WeatherForecast.sln
+++ b/examples/WeatherForecast/WeatherForecast.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers", "..\..\src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherForecast", "src\WeatherForecast\WeatherForecast.csproj", "{40712E50-0FC0-47AA-A9BE-98AA2FB73E59}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherForecast.Contexts", "src\WeatherForecast.Contexts\WeatherForecast.Contexts.csproj", "{86938290-5D7D-43B5-8146-4614FB5820F4}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherForecast.Entities", "src\WeatherForecast.Entities\WeatherForecast.Entities.csproj", "{53CAFB42-4AEB-43F9-B6A1-DAA8EE46F174}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherForecast.Interactors", "src\WeatherForecast.Interactors\WeatherForecast.Interactors.csproj", "{6582ADC8-7DE3-4183-95DF-75D63B784023}"
@@ -31,6 +33,10 @@ Global
{40712E50-0FC0-47AA-A9BE-98AA2FB73E59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40712E50-0FC0-47AA-A9BE-98AA2FB73E59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40712E50-0FC0-47AA-A9BE-98AA2FB73E59}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86938290-5D7D-43B5-8146-4614FB5820F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86938290-5D7D-43B5-8146-4614FB5820F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86938290-5D7D-43B5-8146-4614FB5820F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86938290-5D7D-43B5-8146-4614FB5820F4}.Release|Any CPU.Build.0 = Release|Any CPU
{53CAFB42-4AEB-43F9-B6A1-DAA8EE46F174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{53CAFB42-4AEB-43F9-B6A1-DAA8EE46F174}.Debug|Any CPU.Build.0 = Debug|Any CPU
{53CAFB42-4AEB-43F9-B6A1-DAA8EE46F174}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataContext.cs b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataContext.cs
new file mode 100644
index 000000000..bf12eab45
--- /dev/null
+++ b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataContext.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Linq;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore;
+using WeatherForecast.Entities;
+
+namespace WeatherForecast.Contexts;
+
+[PublicAPI]
+public sealed class WeatherDataContext : DbContext
+{
+ public WeatherDataContext(DbContextOptions options) : base(options)
+ {
+ }
+
+ public DbSet WeatherData { get; set; } = null!;
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ // Map all read-only properties. There is not [Mapped] attribute like [NotMapped].
+ modelBuilder.Entity().Property(weatherData => weatherData.Id);
+ modelBuilder.Entity().Property(weatherData => weatherData.Date);
+ modelBuilder.Entity().Property(temperature => temperature.Id);
+ modelBuilder.Entity().Property(temperature => temperature.UnitName);
+ modelBuilder.Entity().Property(temperature => temperature.UnitSymbol);
+ modelBuilder.Entity().Property(temperature => temperature.Value);
+ modelBuilder.Entity().Property(temperature => temperature.Measured);
+ modelBuilder.Entity().HasMany(weatherData => weatherData.Temperatures).WithOne().HasForeignKey(temperature => temperature.BelongsTo);
+
+ var weatherDataSeed = Enumerable.Range(0, 30).Select(_ => Guid.NewGuid()).Select((id, day) => new WeatherData(id, DateTime.Today.AddDays(day))).ToList();
+ var temperatureSeed = weatherDataSeed.SelectMany(data => Enumerable.Range(0, 23).Select(hour => Temperature.Celsius(data.Id, Random.Shared.Next(-10, 30), data.Date.AddHours(hour)))).ToList();
+
+ modelBuilder.Entity().HasData(temperatureSeed);
+ modelBuilder.Entity().HasData(weatherDataSeed);
+ base.OnModelCreating(modelBuilder);
+ }
+}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataReadOnlyContext.cs b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataReadOnlyContext.cs
new file mode 100644
index 000000000..049cd0f0c
--- /dev/null
+++ b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataReadOnlyContext.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using Microsoft.EntityFrameworkCore;
+using WeatherForecast.Entities;
+using WeatherForecast.Repositories;
+
+namespace WeatherForecast.Contexts;
+
+[PublicAPI]
+public sealed class WeatherDataReadOnlyContext : IWeatherDataReadOnlyRepository
+{
+ private readonly WeatherDataContext _context;
+
+ public WeatherDataReadOnlyContext(WeatherDataContext context)
+ {
+ _context = context;
+ _context.Database.EnsureCreated();
+ }
+
+ public Task> GetAllAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task> GetAllAsync(string latitude, string longitude, DateTime from, DateTime to)
+ {
+ return Task.FromResult>(_context.WeatherData.Include(property => property.Temperatures).OrderBy(weatherData => weatherData.Date).Take(to.Subtract(from).Days));
+ }
+
+ public Task GetAsync(Guid id)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataWriteOnlyContext.cs b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataWriteOnlyContext.cs
new file mode 100644
index 000000000..608ac3cbe
--- /dev/null
+++ b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherDataWriteOnlyContext.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using WeatherForecast.Entities;
+using WeatherForecast.Repositories;
+
+namespace WeatherForecast.Contexts;
+
+[PublicAPI]
+public sealed class WeatherDataWriteOnlyContext : IWeatherDataWriteOnlyRepository
+{
+ public WeatherDataWriteOnlyContext(WeatherDataContext context)
+ {
+ _ = context;
+ }
+
+ public Task CreateAsync(WeatherData weatherData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task UpdateAsync(WeatherData weatherData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task DeleteAsync(WeatherData weatherData)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherForecast.Contexts.csproj b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherForecast.Contexts.csproj
new file mode 100644
index 000000000..6ddfc1c86
--- /dev/null
+++ b/examples/WeatherForecast/src/WeatherForecast.Contexts/WeatherForecast.Contexts.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+
+
+
+
+
+
+
+
+
diff --git a/examples/WeatherForecast/src/WeatherForecast.Entities/HasId.cs b/examples/WeatherForecast/src/WeatherForecast.Entities/HasId.cs
new file mode 100644
index 000000000..db5ea6ec4
--- /dev/null
+++ b/examples/WeatherForecast/src/WeatherForecast.Entities/HasId.cs
@@ -0,0 +1,20 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
+using JetBrains.Annotations;
+
+namespace WeatherForecast.Entities;
+
+[PublicAPI]
+public abstract class HasId
+{
+ [JsonConstructor]
+ public HasId(Guid id)
+ {
+ Id = id;
+ }
+
+ [Key]
+ [JsonPropertyName("id")]
+ public Guid Id { get; }
+}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Entities/Temperature.cs b/examples/WeatherForecast/src/WeatherForecast.Entities/Temperature.cs
index 71fa667d9..d9d54b91f 100644
--- a/examples/WeatherForecast/src/WeatherForecast.Entities/Temperature.cs
+++ b/examples/WeatherForecast/src/WeatherForecast.Entities/Temperature.cs
@@ -1,39 +1,51 @@
using System;
+using System.Text.Json.Serialization;
using JetBrains.Annotations;
namespace WeatherForecast.Entities;
[PublicAPI]
-public readonly struct Temperature
+public sealed class Temperature : HasId
{
- private Temperature(string unitName, string unitSymbol, double value, DateTime measured)
+ [JsonConstructor]
+ public Temperature(Guid id, Guid belongsTo, string unitName, string unitSymbol, double value, DateTime measured) : base(id)
{
+ BelongsTo = belongsTo;
UnitName = unitName;
UnitSymbol = unitSymbol;
Value = value;
Measured = measured;
}
- public static Temperature Kelvin(double value, DateTime measured)
- {
- return new Temperature("Kelvin", "K", value, measured);
- }
-
- public static Temperature Celsius(double value, DateTime measured)
- {
- return new Temperature("degree Celsius", "°C", value, measured);
- }
+ public static Temperature AbsoluteZero { get; } = Temperature.Kelvin(Guid.Empty, 0, DateTime.MinValue);
- public static Temperature Fahrenheit(double value, DateTime measured)
- {
- return new Temperature("degree Fahrenheit", "°F", value, measured);
- }
+ [JsonPropertyName("belongsTo")]
+ public Guid BelongsTo { get; }
+ [JsonPropertyName("unitName")]
public string UnitName { get; }
+ [JsonPropertyName("unitSymbol")]
public string UnitSymbol { get; }
+ [JsonPropertyName("value")]
public double Value { get; }
+ [JsonPropertyName("measured")]
public DateTime Measured { get; }
+
+ public static Temperature Kelvin(Guid belongsTo, double value, DateTime measured)
+ {
+ return new Temperature(Guid.NewGuid(), belongsTo, "Kelvin", "K", value, measured);
+ }
+
+ public static Temperature Celsius(Guid belongsTo, double value, DateTime measured)
+ {
+ return new Temperature(Guid.NewGuid(), belongsTo, "degree Celsius", "°C", value, measured);
+ }
+
+ public static Temperature Fahrenheit(Guid belongsTo, double value, DateTime measured)
+ {
+ return new Temperature(Guid.NewGuid(), belongsTo, "degree Fahrenheit", "°F", value, measured);
+ }
}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherData.cs b/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherData.cs
index ae2324da3..15aad91b0 100644
--- a/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherData.cs
+++ b/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherData.cs
@@ -1,27 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text.Json.Serialization;
using JetBrains.Annotations;
namespace WeatherForecast.Entities;
[PublicAPI]
-public readonly struct WeatherData
+public sealed class WeatherData : HasId
{
- public WeatherData(DateTime date, IEnumerable measurements)
+ public WeatherData(Guid id, DateTime date) : this(id, date, new List())
+ {
+ // Entity Framework constructor.
+ }
+
+ [JsonConstructor]
+ public WeatherData(Guid id, DateTime date, IList temperatures) : base(id)
{
- IReadOnlyCollection temperatures = measurements.ToList();
Date = date;
- Minimum = temperatures.OrderBy(temperature => temperature.Value).FirstOrDefault();
- Maximum = temperatures.OrderBy(temperature => temperature.Value).LastOrDefault();
+ Minimum = temperatures.OrderBy(temperature => temperature.Value).DefaultIfEmpty(Temperature.AbsoluteZero).First();
+ Maximum = temperatures.OrderBy(temperature => temperature.Value).DefaultIfEmpty(Temperature.AbsoluteZero).Last();
Temperatures = temperatures;
}
+ [JsonPropertyName("date")]
public DateTime Date { get; }
+ [JsonIgnore]
public Temperature Minimum { get; }
+ [JsonIgnore]
public Temperature Maximum { get; }
- public IEnumerable Temperatures { get; }
+ [JsonPropertyName("temperatures")]
+ public IList Temperatures { get; }
}
diff --git a/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherForecast.Entities.csproj b/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherForecast.Entities.csproj
index 1975642a4..aa2dc7a92 100644
--- a/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherForecast.Entities.csproj
+++ b/examples/WeatherForecast/src/WeatherForecast.Entities/WeatherForecast.Entities.csproj
@@ -5,5 +5,7 @@
+
+
diff --git a/examples/WeatherForecast/src/WeatherForecast.Repositories/WeatherDataReadOnlyRepository.cs b/examples/WeatherForecast/src/WeatherForecast.Repositories/WeatherDataReadOnlyRepository.cs
index 475ace153..9c402d4eb 100644
--- a/examples/WeatherForecast/src/WeatherForecast.Repositories/WeatherDataReadOnlyRepository.cs
+++ b/examples/WeatherForecast/src/WeatherForecast.Repositories/WeatherDataReadOnlyRepository.cs
@@ -20,7 +20,7 @@ public Task> GetAllAsync()
public Task> GetAllAsync(string latitude, string longitude, DateTime from, DateTime to)
{
- return Task.FromResult(Enumerable.Range(0, to.Subtract(from).Days).Select(day => DateTime.Today.AddDays(day)).Select(day => new WeatherData(day, Enumerable.Range(0, 12).Select(hour => Temperature.Celsius(Random.Value.Next(-10, 30), DateTime.Today.AddHours(hour))))));
+ return Task.FromResult(Enumerable.Range(0, to.Subtract(from).Days).Select(_ => Guid.NewGuid()).Select((id, day) => new WeatherData(id, DateTime.Today.AddDays(day), Enumerable.Range(0, 23).Select(hour => Temperature.Celsius(id, Random.Value.Next(-10, 30), DateTime.Today.AddDays(day).AddHours(hour))).ToList())));
}
public Task GetAsync(Guid id)
diff --git a/examples/WeatherForecast/src/WeatherForecast/Program.cs b/examples/WeatherForecast/src/WeatherForecast/Program.cs
index 1f5c819cd..11ba0e306 100644
--- a/examples/WeatherForecast/src/WeatherForecast/Program.cs
+++ b/examples/WeatherForecast/src/WeatherForecast/Program.cs
@@ -1,6 +1,9 @@
using Microsoft.AspNetCore.Builder;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Fast.Components.FluentUI;
+using WeatherForecast.Contexts;
using WeatherForecast.Interactors.SearchCityOrZipCode;
using WeatherForecast.Repositories;
@@ -9,9 +12,22 @@
builder.Services.AddServerSideBlazor();
builder.Services.AddHttpClient();
builder.Services.AddFluentUIComponents();
-builder.Services.AddSingleton();
-builder.Services.AddSingleton();
-builder.Services.AddSingleton();
+
+var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
+
+if (string.IsNullOrWhiteSpace(connectionString))
+{
+ builder.Services.AddSingleton();
+ builder.Services.AddSingleton();
+ builder.Services.AddSingleton();
+}
+else
+{
+ builder.Services.AddDbContext(options => options.UseSqlServer(connectionString));
+ builder.Services.AddScoped();
+ builder.Services.AddScoped();
+ builder.Services.AddScoped();
+}
var app = builder.Build();
app.UseExceptionHandler("/Error");
diff --git a/examples/WeatherForecast/src/WeatherForecast/WeatherForecast.csproj b/examples/WeatherForecast/src/WeatherForecast/WeatherForecast.csproj
index 283f74a2e..bc3a734b7 100644
--- a/examples/WeatherForecast/src/WeatherForecast/WeatherForecast.csproj
+++ b/examples/WeatherForecast/src/WeatherForecast/WeatherForecast.csproj
@@ -5,9 +5,11 @@
false
+
+
diff --git a/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecast.Test.csproj b/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecast.Test.csproj
index d777a6778..2ee7c717b 100644
--- a/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecast.Test.csproj
+++ b/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecast.Test.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecastContainer.cs b/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecastContainer.cs
index e34bd02d2..cf7580ae0 100644
--- a/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecastContainer.cs
+++ b/examples/WeatherForecast/tests/WeatherForecast.Test/WeatherForecastContainer.cs
@@ -3,7 +3,9 @@
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using DotNet.Testcontainers.Builders;
+using DotNet.Testcontainers.Configurations;
using DotNet.Testcontainers.Containers;
+using DotNet.Testcontainers.Networks;
using JetBrains.Annotations;
using Xunit;
@@ -16,7 +18,11 @@ public sealed class WeatherForecastContainer : HttpClient, IAsyncLifetime
private static readonly WeatherForecastImage Image = new();
- private readonly IDockerContainer _container;
+ private readonly IDockerNetwork _weatherForecastNetwork;
+
+ private readonly IDockerContainer _mssqlContainer;
+
+ private readonly IDockerContainer _weatherForecastContainer;
public WeatherForecastContainer()
: base(new HttpClientHandler
@@ -24,13 +30,33 @@ public WeatherForecastContainer()
ServerCertificateCustomValidationCallback = (_, certificate, _, _) => Certificate.Equals(certificate)
})
{
- _container = new TestcontainersBuilder()
+ const string weatherForecastStorage = "weatherForecastStorage";
+
+ var mssqlConfiguration = new MsSqlTestcontainerConfiguration();
+ mssqlConfiguration.Password = Guid.NewGuid().ToString("D");
+ mssqlConfiguration.Database = Guid.NewGuid().ToString("D");
+
+ var connectionString = $"server={weatherForecastStorage};user id=sa;password={mssqlConfiguration.Password};database={mssqlConfiguration.Database}";
+
+ _weatherForecastNetwork = new TestcontainersNetworkBuilder()
+ .WithName(Guid.NewGuid().ToString("D"))
+ .Build();
+
+ _mssqlContainer = new TestcontainersBuilder()
+ .WithDatabase(mssqlConfiguration)
+ .WithNetwork(_weatherForecastNetwork)
+ .WithNetworkAliases(weatherForecastStorage)
+ .Build();
+
+ _weatherForecastContainer = new TestcontainersBuilder()
.WithImage(Image)
- .WithStartupCallback((_, ct) => Task.Delay(TimeSpan.FromSeconds(1), ct)) // For demonstration only, use a wait strategy instead.
+ .WithNetwork(_weatherForecastNetwork)
.WithPortBinding(WeatherForecastImage.HttpsPort, true)
.WithEnvironment("ASPNETCORE_URLS", "https://+")
.WithEnvironment("ASPNETCORE_Kestrel__Certificates__Default__Path", WeatherForecastImage.CertificateFilePath)
.WithEnvironment("ASPNETCORE_Kestrel__Certificates__Default__Password", WeatherForecastImage.CertificatePassword)
+ .WithEnvironment("ConnectionStrings__DefaultConnection", connectionString)
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(WeatherForecastImage.HttpsPort))
.Build();
}
@@ -39,7 +65,13 @@ public async Task InitializeAsync()
await Image.InitializeAsync()
.ConfigureAwait(false);
- await _container.StartAsync()
+ await _weatherForecastNetwork.CreateAsync()
+ .ConfigureAwait(false);
+
+ await _mssqlContainer.StartAsync()
+ .ConfigureAwait(false);
+
+ await _weatherForecastContainer.StartAsync()
.ConfigureAwait(false);
}
@@ -48,7 +80,13 @@ public async Task DisposeAsync()
await Image.DisposeAsync()
.ConfigureAwait(false);
- await _container.DisposeAsync()
+ await _weatherForecastContainer.DisposeAsync()
+ .ConfigureAwait(false);
+
+ await _mssqlContainer.DisposeAsync()
+ .ConfigureAwait(false);
+
+ await _weatherForecastNetwork.DeleteAsync()
.ConfigureAwait(false);
}
@@ -56,7 +94,7 @@ public void SetBaseAddress()
{
try
{
- var uriBuilder = new UriBuilder("https", _container.Hostname, _container.GetMappedPublicPort(WeatherForecastImage.HttpsPort));
+ var uriBuilder = new UriBuilder("https", _weatherForecastContainer.Hostname, _weatherForecastContainer.GetMappedPublicPort(WeatherForecastImage.HttpsPort));
BaseAddress = uriBuilder.Uri;
}
catch