Errata (19 items)
If you find any mistakes, then please raise an issue in this repository or email me at markjprice (at) gmail.com.
- Breaking change in Aspire 8.2
- Renaming "Components" to "Integrations" in Aspire 8.2 and later
- Page 39 - Making the Most of the Tools in Your Code Editor
- Page 143 - Creating code with objects to view
- Page 285 - Encrypting symmetrically with AES
- Page 305 - Implementing authentication and authorization
- Page 331 - Adding session memory and enabling multiple functions
- Page 333 - Adding session memory and enabling multiple functions
- Page 341 - OllamaSharp .NET package
- Page 356 - Registering multiple implementations
- Page 388 - Creating a SUT, Page 401 - Controlling test fixtures
- Page 392 - Test methods with parameters
- Page 406 - Libraries for mocking
- Page 415 - Generating fake data with Bogus
- Page 427 - Walkthrough of an example integration test
- Page 509 - Generating tests with the Playwright Inspector
- Page 536 - Docker image hierarchy and layers
- Page 579 - Docker versus Podman for containers
- Page 622 - Builder pattern example
To use .NET Aspire 8.2, you will need to make sure that you have the latest version of the workload installed as well as make sure that your AppHost project references the latest version of the Aspire.Hosting.AppHost
package. Otherwise, you may see a build error similar to this:
xxx.AppHost is a .NET Aspire AppHost project that needs a package reference to Aspire.Hosting.AppHost version 8.2.0 or above to work correctly.
To fix it, make sure that your AppHost project file contains the following package reference:
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
Learn more about this breaking change at the following link: dotnet/aspire#5501.
The Aspire team has renamed "Components" to "Integrations" in Aspire 8.2 and later. You can learn more at the following link: https://devblogs.microsoft.com/dotnet/announcing-dotnet-aspire-8-2/.
Thanks to Giuseppe Guerra for raising this issue on March 25, 2025.
In the first paragraph I wrote, "interactive development environments (IDEs)", when I should have written, "integrated development environments (IDEs)".
Thanks to Giuseppe Guerra for raising this issue on March 24, 2025.
In Step 2, I wrote, "import System.Convert
, System.Convert
", but I should have written, "import System.Console
, System.Convert
"
Thanks to P9avel for raising this issue on September 26, 2024.
In Step 7, in the Decrypt
method, in the using (MemoryStream ms = new())
code block, I call the aes.CreateDecryptor()
method twice, as shown in the following code:
using (MemoryStream ms = new())
{
using (ICryptoTransform transformer = aes.CreateDecryptor())
{
using (CryptoStream cs = new(
ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
...
The second call should be a reference to the transformer
variable, as shown in the following code:
using (MemoryStream ms = new())
{
using (ICryptoTransform transformer = aes.CreateDecryptor())
{
using (CryptoStream cs = new(
ms, transformer, CryptoStreamMode.Write))
{
...
Thanks to OpticOrange for raising this issue on February 9, 2025.
In Step 11, I wrote Pa$$word
instead of Pa$$w0rd
. I made the same mistake in Step 13, and on page 306 in Step 4 and Step 5.
Thanks to lenara122 for raising this issue on February 18, 2025.
On page 319, the configuration uses Semantic Kernel package version 1.13.0
which was the current version when writing the book. If you use the latest version available in February 2025, version 1.37.0
, then there are some changes needed to migrate to the newer version, as described at the following link: https://learn.microsoft.com/en-us/semantic-kernel/support/migration/function-calling-migration-guide?pivots=programming-language-csharp.
In Step 2, the statement to set the options, as shown in the following code:
OpenAIPromptExecutionSettings options = new()
{ ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
Should be updated to the following code:
PromptExecutionSettings options = new()
{ FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
Thanks to Giuseppe Guerra for raising this issue on March 24, 2025.
After Step 7, I show the output from entering the question, but in the middle of the output, the text highlighted in yellow should be a separate Step 8, as shown in the following figure:
Thanks to P9avel for raising this issue on September 29, 2024.
In Step 2, I wrote, "add references to packages for Spectre Console and Ollama" when I should have written, "add references to packages for Spectre Console and OllamaSharp".
Thanks to P9avel for raising this issue on October 2, 2024.
In the first statement of the code block, I mis-cased the method name as AddKeyedsingleton
. It should be AddKeyedSingleton
.
Thanks to P9avel for raising this issue on October 2, 2024.
In Step 2 on both pages 388 and 401, I wrote, "treat errors as errors", when I should have written "treat warnings as errors".
Thanks to P9avel for raising this issue on October 2, 2024.
In the third bullet I wrote, "Decorate the test method with [ClassData]
and reference a method that represents an IEnumerable
of arrays of types."
I should have written, "Decorate the test method with [ClassData]
and reference a class that derives from TheoryData<T1, T2, ...>
and call the inherited Add
method in its constructor to add sets of expected parameter and return values."
In the warning box, I wrote, "You can read the release notes at the following link: https://github.com/devlooped/moq/blob/main/CHANGELOG.md#4200-2023-08-07." But this link is now broken.
In the next edition, I will replace that sentence with the following, "You can read the pull request at the following link:devlooped/moq#1363."
Thanks to P9avel for raising this issue on October 3, 2024.
In Table 11.7, f.Finance.Currency().Code
should be Finance.Currency().Code
. I don't know how the extra f.
got there!
Thanks to P9avel for raising this issue on October 7, 2024.
I wrote, "The preceding code is a unit test class named GetById
..." when I should have written, "The preceding code is an integration test class named GetById
..."
Thanks to P9avel for raising this issue on October 9, 2024.
In the paths to "start the Playwright Inspector with emulation options like setting a view port size", I typed a slash /
instead of a dot .
between the 8
and 0
. For example, I typed net8/0
instead of net8.0
.
Thanks to P9avel for raising this issue on October 11, 2024.
Figure 15.7 has multiple mistakes, like Layer 2 had an erroneous FROM
before WORKDIR
, so I have created a fixed image here:
I have also made the figure example match the actual Dockerfile
that you will create on page 542 in Step 4, as shown in the following code:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /Chapter15
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/runtime:8.0
WORKDIR /Chapter15
COPY --from=build-env /Chapter15/out .
ENTRYPOINT ["dotnet", "AboutMyEnvironment.dll"]
Thanks to P9avel for raising this issue on October 14, 2024.
Podman pro should be Podman pros.
Thanks to P9avel for raising this issue on October 15, 2024.
I wrote, "First, you create the Builder Interface, with methods to set each of the product’s properties, and a
Build
method to return the constructed product, as shown in the following code:"
Both instances of the word "product" should be "Product" because in the context of the Builder pattern, it refers to the term that means the object being built. In the next edition I will fix this.