建立自訂 .NET.NET Aspire 主機託管整合
.NET .NET Aspire 藉由提供可重複使用的建置組塊來快速排列應用程式相依性,並將其公開給您自己的程式碼,藉此改善開發體驗。 以 Aspire為基礎的應用程式的主要建置組塊之一是 資源。 請考慮下列程式代碼:
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("cache");
var db = builder.AddPostgres("pgserver")
.AddDatabase("inventorydb");
builder.AddProject<Projects.InventoryService>("inventoryservice")
.WithReference(redis)
.WithReference(db);
在上述程式代碼中,有四個資源表示:
-
cache
:Redis 容器。 -
pgserver
:Postgres 容器。 -
inventorydb
:裝載在pgserver
上的資料庫。 -
inventoryservice
: ASP.NET Core 應用程式。
大部分 .NET.NET Aspire相關程式代碼,都是開發人員平均撰寫的程式代碼,以將資源新增至 應用程式模型,並在兩者之間建立參考為中心。
.NET .NET Aspire 自定義資源的重要元素
在 .NET.NET Aspire 中建置自訂資源需要下列各項:
- 實作 IResource 的自定義資源類型
- 為 IDistributedApplicationBuilder 的擴充方法,名為
Add{CustomResource}
,其中{CustomResource}
是自定義資源的名稱。
當自訂資源需要選用設定時,開發人員可能會想要實作 With*
後綴擴展方法,使這些設定選項便於探索,並且可以使用 建構器模式。
實際範例:MailDev
為了協助瞭解如何開發自定義資源,本文示範如何建置 MailDev的自定義資源範例。 MailDev 是一種開放原始碼工具,提供本機郵件 server,其設計目的是讓開發人員在其應用程式中測試電子郵件傳送行為。 如需詳細資訊,請參閱 MailDevGitHub 存放庫。
在此範例中,您會為您所建立 MailDev 資源建立新的 .NET Aspire 項目作為測試環境。 雖然您可以在現有的 .NET Aspire 專案中建立自定義資源,但最好考慮自定義資源是否可以跨多個 .NET Aspire型解決方案使用,而且應該開發為可重複使用的整合。
設定入門專案
建立新的 .NET.NET Aspire 專案,用來測試我們正在開發的新資源。
dotnet new aspire -o MailDevResource
cd MailDevResource
dir
建立項目之後,您應該會看到包含下列項目的清單:
-
MailDevResource.AppHost
:應用程式主機 用來測試自定義資源。 -
MailDevResource.ServiceDefaults
:服務將 預設配置用於服務相關專案。 -
MailDevResource.sln
:參考這兩個專案的方案檔。
執行下列命令,確認專案可以順利建置並執行:
dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj
主控台輸出看起來應該如下所示:
Building...
info: Aspire.Hosting.DistributedApplication[0]
Aspire version: 9.0.0
info: Aspire.Hosting.DistributedApplication[0]
Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
Application host directory is:
..\docs-aspire\docs\extensibility\snippets\MailDevResource\MailDevResource.AppHost
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17251
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17251/login?t=928db244c720c5022a7a9bf5cf3a3526
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
選取瀏覽器 中的
按 Ctrl+C 關閉應用程式(您可以關閉瀏覽器索引標籤)。
建立資源擴展庫
.NET Aspire 資源只是包含在一個類別庫中且參考 .NET Aspire 裝載庫(Aspire.Hosting
)的類別和方法。 藉由將資源放在個別專案中,您可以更輕鬆地在以 .NET.NET Aspire為基礎的應用程式之間共用資源,並有可能將其打包並在 NuGet 上分享。
建立名為 MailDev的類別庫專案。載入。
dotnet new classlib -o MailDev.Hosting
將
Aspire.Hosting
新增至類別庫作為套件參考。dotnet add ./MailDev.Hosting/MailDev.Hosting.csproj package Aspire.Hosting --version 9.0.0
重要
您在此處指定的版本應該符合已安裝 .NET.NET Aspire 工作負載的版本。
將類別庫參考新增至 MailDevResource.AppHost 專案。
dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
將類別庫專案新增至方案檔。
dotnet sln ./MailDevResource.sln add ./MailDev.Hosting/MailDev.Hosting.csproj
執行下列步驟之後,您可以啟動專案:
dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj
這會導致主控台顯示警告:
.\.nuget\packages\aspire.hosting.apphost\9.0.0\build\Aspire.Hosting.AppHost.targets(174,5): warning ASPIRE004: '..\MailDev.Hosting\MailDev.Hosting.csproj' is referenced by an A
spire Host project, but it is not an executable. Did you mean to set IsAspireProjectResource="false"? [D:\source\repos\docs-aspire\docs\extensibility\snippets\MailDevResource\MailDevResource.AppHost\MailDevRe
source.AppHost.csproj]
這是因為 .NET.NET Aspire 會將應用程式主機中的項目參考視為服務專案。 若要告訴 .NET.NET Aspire 項目參考應該視為非服務專案,請修改 MailDev.Hosting
專案的 MailDevResource.AppHostMailDevResource.AppHost.csproj 檔案參考,如下所示:
<ItemGroup>
<!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this
reference as a standard project reference and not attempt to generate
a metadata file -->
<ProjectReference Include="..\MailDev.Hosting\MailDev.Hosting.csproj"
IsAspireProjectResource="false" />
</ItemGroup>
現在當您啟動應用程式主機時,主控控台不會顯示任何警告。
定義資源類型
MailDev.裝載 類別庫包含資源類型和擴充方法以新增資源至應用程式主機。 您應該先考慮使用自訂資源時想要提供給開發人員的體驗。 在這裡自訂資源的情況下,您希望開發人員能夠撰寫如下的程式代碼:
var builder = DistributedApplication.CreateBuilder(args);
var maildev = builder.AddMailDev("maildev");
builder.AddProject<Projects.NewsletterService>("newsletterservice")
.WithReference(maildev);
若要達成此目的,您需要名為 MailDevResource
的自定義資源,以實作 IResourceWithConnectionString,讓取用者可以搭配 WithReference 擴充功能來插入 MailDevserver 的連線詳細數據作為連接字串。
MailDev 可作為容器資源,因此您也會想要衍生自 ContainerResource,以便我們可以在 .NET.NET Aspire中使用各種預先存在的容器焦點擴充功能。
以下列程式代碼取代 MailDev.Hosting
專案中 Class1.cs 檔案的內容,並將檔案重新命名為 MailDevResource.cs:
// For ease of discovery, resource types should be placed in
// the Aspire.Hosting.ApplicationModel namespace. If there is
// likelihood of a conflict on the resource name consider using
// an alternative namespace.
namespace Aspire.Hosting.ApplicationModel;
public sealed class MailDevResource(string name) : ContainerResource(name), IResourceWithConnectionString
{
// Constants used to refer to well known-endpoint names, this is specific
// for each resource type. MailDev exposes an SMTP endpoint and a HTTP
// endpoint.
internal const string SmtpEndpointName = "smtp";
internal const string HttpEndpointName = "http";
// An EndpointReference is a core .NET Aspire type used for keeping
// track of endpoint details in expressions. Simple literal values cannot
// be used because endpoints are not known until containers are launched.
private EndpointReference? _smtpReference;
public EndpointReference SmtpEndpoint =>
_smtpReference ??= new(this, SmtpEndpointName);
// Required property on IResourceWithConnectionString. Represents a connection
// string that applications can use to access the MailDev server. In this case
// the connection string is composed of the SmtpEndpoint endpoint reference.
public ReferenceExpression ConnectionStringExpression =>
ReferenceExpression.Create(
$"smtp://{SmtpEndpoint.Property(EndpointProperty.Host)}:{SmtpEndpoint.Property(EndpointProperty.Port)}"
);
}
在上述自定義資源中,EndpointReference 和 ReferenceExpression 是數種實作介面集合的類型範例,例如 IManifestExpressionProvider、IValueProvider和 IValueWithReferences。 如需這些類型及其角色在 .NET.NET Aspire的詳細資訊,請參閱 技術詳細資料。
定義資源擴展
若要讓開發人員輕鬆地使用自定義資源,必須將名為 AddMailDev
的擴充方法新增至 MailDev.Hosting 專案。
AddMailDev
擴充方法負責設定資源,使其可以成功作為容器啟動。
將下列程式代碼新增至 MailDev.Hosting 專案中名為 MailDevResourceBuilderExtensions.cs 的新檔案中:
using Aspire.Hosting.ApplicationModel;
// Put extensions in the Aspire.Hosting namespace to ease discovery as referencing
// the .NET Aspire hosting package automatically adds this namespace.
namespace Aspire.Hosting;
public static class MailDevResourceBuilderExtensions
{
/// <summary>
/// Adds the <see cref="MailDevResource"/> to the given
/// <paramref name="builder"/> instance. Uses the "2.1.0" tag.
/// </summary>
/// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
/// <param name="name">The name of the resource.</param>
/// <param name="httpPort">The HTTP port.</param>
/// <param name="smtpPort">The SMTP port.</param>
/// <returns>
/// An <see cref="IResourceBuilder{MailDevResource}"/> instance that
/// represents the added MailDev resource.
/// </returns>
public static IResourceBuilder<MailDevResource> AddMailDev(
this IDistributedApplicationBuilder builder,
string name,
int? httpPort = null,
int? smtpPort = null)
{
// The AddResource method is a core API within .NET Aspire and is
// used by resource developers to wrap a custom resource in an
// IResourceBuilder<T> instance. Extension methods to customize
// the resource (if any exist) target the builder interface.
var resource = new MailDevResource(name);
return builder.AddResource(resource)
.WithImage(MailDevContainerImageTags.Image)
.WithImageRegistry(MailDevContainerImageTags.Registry)
.WithImageTag(MailDevContainerImageTags.Tag)
.WithHttpEndpoint(
targetPort: 1080,
port: httpPort,
name: MailDevResource.HttpEndpointName)
.WithEndpoint(
targetPort: 1025,
port: smtpPort,
name: MailDevResource.SmtpEndpointName);
}
}
// This class just contains constant strings that can be updated periodically
// when new versions of the underlying container are released.
internal static class MailDevContainerImageTags
{
internal const string Registry = "docker.io";
internal const string Image = "maildev/maildev";
internal const string Tag = "2.1.0";
}
驗證應用程式主機內的自定義整合
現在,自定義資源的基本結構已完成,現在可以在實際的AppHost專案中進行測試。 在 MailDevResource.AppHost 項目中開啟 Program.cs 檔案,並使用下列程式代碼加以更新:
var builder = DistributedApplication.CreateBuilder(args);
var maildev = builder.AddMailDev("maildev");
builder.Build().Run();
更新 Program.cs 檔案之後,請啟動應用程式主機項目並開啟儀錶板:
dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj
在幾分鐘后,儀錶板會顯示 maildev
資源正在執行,且有一個超連結可供流覽至 MailDev Web 應用程式,其中顯示應用程式傳送的每個電子郵件內容。
.NET .NET Aspire 儀錶板看起來應該如下所示:
MailDev Web 應用程式看起來應該如下所示:
將 .NET 服務專案新增至應用程式主機以進行測試
一旦 .NET Aspire 成功啟動 MailDev 整合,就可以在 .NET 專案中取用 MailDev 的連接資訊。 在
-
裝載套件:用來代表應用程式模型中的資源。
Aspire.Hosting.Redis
-
元件套件:用來設定及使用 client 函式庫。
Aspire.StackExchange.Redis
Aspire.StackExchange.Redis.DistributedCaching
Aspire.StackExchange.Redis.OutputCaching
在 MailDev 資源的情況下,.NET 平台已經有簡單的郵件傳輸通訊協定 (SMTP) client,格式為 SmtpClient。 在此範例中,為了簡單起見,您可以使用此現有的 API,不過其他資源類型可能受益於自定義整合連結庫來協助開發人員。
若要測試端到端場景,您需要一個 .NET 專案,我們可以將連線資訊插入到用於 MailDev 資源的專案中。 新增 Web API 專案:
建立名為 MailDevResource.NewsletterService的新 .NET 專案。
dotnet new webapi --use-minimal-apis -o MailDevResource.NewsletterService
新增 MailDev.Hosting 項目的參考。
dotnet add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
新增 MailDevResource.AppHost 項目的參考。
dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
將新專案新增至方案檔。
dotnet sln ./MailDevResource.sln add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
新增專案並更新參考之後,請開啟 MailDevResource.AppHost.csproj 專案中的 Program.cs,並更新原始碼檔,如下所示:
var builder = DistributedApplication.CreateBuilder(args);
var maildev = builder.AddMailDev("maildev");
builder.AddProject<Projects.MailDevResource_NewsletterService>("newsletterservice")
.WithReference(maildev);
builder.Build().Run();
更新 Program.cs 檔案之後,請再次啟動應用程式主機。 然後確認電子報服務已啟動,且已將環境變數 ConnectionStrings__maildev
新增至進程。 從 [資源] 頁面上,尋找 newsletterservice
數據列,然後選取 [詳細數據] 數據行上的 [檢視] 連結:
上述螢幕快照顯示 newsletterservice
項目的環境變數。
ConnectionStrings__maildev
環境變數是 maildev
資源插入項目的連接字串。
使用連接字串傳送訊息
為了使用被注入到電子報服務專案中的 SMTP 連線詳細數據,請將 SmtpClient 實例作為單例注入到相依性注入容器中。 將下列代碼新增至 MailDevResource.NewsletterService 專案中的 Program.cs 檔案,以設定單例服務。 在 Program
類別中,緊接在 // Add services to the container
批注之後,新增下列程序代碼:
builder.Services.AddSingleton<SmtpClient>(sp =>
{
var smtpUri = new Uri(builder.Configuration.GetConnectionString("maildev")!);
var smtpClient = new SmtpClient(smtpUri.Host, smtpUri.Port);
return smtpClient;
});
提示
不過,此代碼段依賴官方 SmtpClient
;在某些平臺上,此類型已過時,不建議用於其他平臺。 如需使用 MailKit的更現代化方法,請參閱 建立自訂 .NET Aspireclient 整合功能。
若要測試 client,請將兩個簡單的 subscribe
和 unsubscribe
POST 方法新增至電子報服務。 新增下列程序代碼,取代 MailDevResource.NewsletterService 專案的 Program.cs 檔案中的 “weatherforecast MapGet
” 呼叫,以設定 ASP.NET Core 路由:
app.MapPost("/subscribe", async (SmtpClient smtpClient, string email) =>
{
using var message = new MailMessage("newsletter@yourcompany.com", email)
{
Subject = "Welcome to our newsletter!",
Body = "Thank you for subscribing to our newsletter!"
};
await smtpClient.SendMailAsync(message);
});
app.MapPost("/unsubscribe", async (SmtpClient smtpClient, string email) =>
{
using var message = new MailMessage("newsletter@yourcompany.com", email)
{
Subject = "You are unsubscribed from our newsletter!",
Body = "Sorry to see you go. We hope you will come back soon!"
};
await smtpClient.SendMailAsync(message);
});
提示
如果您的程式代碼編輯器不會自動新增 System.Net.Mail
和 Microsoft.AspNetCore.Mvc
命名空間至 Program.cs,請記得參考這些命名空間。
更新 Program.cs 檔案之後,請啟動應用程式主機並使用您的瀏覽器,或 curl
來點擊下列 URL(或者,如果您使用 Visual Studio 您可以使用 .http
檔案):
POST /subscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json
若要使用此 API,您可以使用 curl
來傳送要求。 下列 curl
命令會將 HTTP POST
請求發送至 subscribe
端點,並期待使用 email
查詢字串值來訂閱電子報。
Content-Type
標頭設定為 application/json
,以顯示請求正文的格式為 JSON:
curl -H "Content-Type: application/json" --request POST https://localhost:7251/subscribe?email=test@test.com
下一個 API 是 unsubscribe
端點。 此端點用來取消訂閱電子報。
POST /unsubscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json
若要取消訂閱電子報,您可以使用下列 curl
命令,將 email
參數傳遞至 unsubscribe
端點做為查詢字串:
curl -H "Content-Type: application/json" --request POST https://localhost:7251/unsubscribe?email=test@test.com
提示
請確定您將 https://localhost:7251
取代為正確的 localhost 埠(您正在執行的應用程式主機 URL)。
如果這些 API 呼叫傳回成功的回應 (HTTP 200, Ok),則您應該能夠在儀錶板的 maildev
資源上選取 ,而 MailDev UI 會顯示已傳送至 SMTP 端點的電子郵件。
技術詳細數據
在下列各節中,會討論各種技術詳細數據,這些詳細數據對於開發 .NET.NET Aspire的自定義資源時很重要。
保護網路
在此範例中,MailDev 資源是透過 HTTP 和 SMTP 向主電腦公開的容器資源。 MailDev 資源是開發工具,不適用於生產環境。 若要改用 HTTPS,請參閱 MailDev:設定 HTTPS。
開發公開網路端點的自定義資源時,請務必考慮資源的安全性影響。 例如,如果資源是資料庫,請務必確保資料庫安全且連接字串不會公開至公用因特網。
ReferenceExpression
和 EndpointReference
類型
在上述程式代碼中,MailDevResource
有兩個屬性:
-
SmtpEndpoint
:EndpointReference 類型。 -
ConnectionStringExpression
:ReferenceExpression 類型。
這些類型是在幾種不同類型中之一,用於整個 .NET Aspire,藉以表示組態數據,而該數據直到 .NET Aspire 專案執行或透過 Azure Developer CLI(azd
)工具發佈至雲端後才會最終確定。
這些類型有助於解決的基本問題是延遲解決具體組態資訊,直到 所有 資訊可用為止。
例如,MailDevResource
會公開 ConnectionStringExpression
這個屬性以符合 IResourceWithConnectionString 介面的需求。 屬性的類型是 ReferenceExpression,並且是透過將插值字串傳遞至 Create 方法來建立的。
public ReferenceExpression ConnectionStringExpression =>
ReferenceExpression.Create(
$"smtp://{SmtpEndpoint.Property(EndpointProperty.Host)}:{SmtpEndpoint.Property(EndpointProperty.Port)}"
);
Create 方法的簽章如下所示:
public static ReferenceExpression Create(
in ExpressionInterpolatedStringHandler handler)
這不是一般的 String 參數。 方法會使用 內插字串處理模式,來擷取內插字串範本及其內引用的值,以允許客製化處理。 在 .NET.NET Aspire的情況下,這些詳細數據會擷取在 ReferenceExpression 中,當插補字串中參考的每個值都可供使用時進行評估。
以下是執行流程的運作方式:
- 實作 IResourceWithConnectionString 的資源會新增至模型(例如,
AddMailDev(...)
)。 -
IResourceBuilder<MailDevResource>
傳遞至 WithReference,該方法擁有專為處理 IResourceWithConnectionString 實作者而設計的特殊重載。 -
WithReference
會將資源包裝在 ConnectionStringReference 實例中,並且物件被捕捉在 .NET.NET Aspire 專案建置並開始執行後評估的 EnvironmentCallbackAnnotation 中。 - 當參考連接字串的進程 .NET.NET Aspire 開始時,就會開始評估表達式。 它會先取得 ConnectionStringReference,並呼叫 IValueProvider.GetValueAsync。
-
GetValueAsync
方法會取得 ConnectionStringExpression 屬性的值,以取得 ReferenceExpression 實例。 - IValueProvider.GetValueAsync 方法接著會呼叫 GetValueAsync,以處理先前擷取的插補字串。
- 因為插補字串包含其他參考型別的參考,例如 EndpointReference 它們也會進行評估,並取代實際值(此時可以使用)。
指令清單發佈
IManifestExpressionProvider 介面的設計目的是要解決在部署時共用資源之間的連線信息問題。
.NET
.NET Aspire 內部循環網路概觀會說明此特定問題的解決方案。 與在本機開發類似,許多值都是配置應用程式所必須的,但在應用程式透過像是 azd
(Azure Developer CLI)的工具部署之前,這些值無法確定。
若要解決此問題,.NET.NET Aspire 會產生指令清單檔案,azd
和其他部署工具加以解譯。 而不是為資源之間的連接資訊指定具體值,使用表達式語法,部署工具會評估它。 一般而言,開發人員看不到指令清單檔案,但可能會產生一個進行手動檢查。 下列命令可用於應用程式主機上,以產生指令清單。
dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj -- --publisher manifest --output-path aspire-manifest.json
這個指令會產生如下的清單檔案:
{
"resources": {
"maildev": {
"type": "container.v0",
"connectionString": "smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port}",
"image": "docker.io/maildev/maildev:2.1.0",
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http",
"targetPort": 1080
},
"smtp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 1025
}
}
},
"newsletterservice": {
"type": "project.v0",
"path": "../MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj",
"env": {
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
"ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true",
"ConnectionStrings__maildev": "{maildev.connectionString}"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http"
},
"https": {
"scheme": "https",
"protocol": "tcp",
"transport": "http"
}
}
}
}
}
因為 MailDevResource
實作 IResourceWithConnectionString.NET.NET Aspire 中的指令清單發佈邏輯知道,即使 MailDevResource
是容器資源,它也需要 connectionString
字段。
connectionString
欄位會參考指令清單中 maildev
資源的其他部分,以產生最終字串:
{
// ... other content omitted.
"connectionString": "smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port}"
}
.NET .NET Aspire 知道如何形成此字串,因為它會查看 ConnectionStringExpression,並透過 IManifestExpressionProvider 介面建置最終字串(與 IValueProvider 介面使用的方式大致相同)。
MailDevResource
會自動包含在指令清單中,因為它衍生自 ContainerResource。 資源作者可以選擇在資源生成器上使用 ExcludeFromManifest 擴充方法來抑制輸出內容至清單。
public static IResourceBuilder<MailDevResource> AddMailDev(
this IDistributedApplicationBuilder builder,
string name,
int? httpPort = null,
int? smtpPort = null)
{
var resource = new MailDevResource(name);
return builder.AddResource(resource)
.WithImage(MailDevContainerImageTags.Image)
.WithImageRegistry(MailDevContainerImageTags.Registry)
.WithImageTag(MailDevContainerImageTags.Tag)
.WithHttpEndpoint(
targetPort: 1080,
port: httpPort,
name: MailDevResource.HttpEndpointName)
.WithEndpoint(
targetPort: 1025,
port: smtpPort,
name: MailDevResource.SmtpEndpointName)
.ExcludeFromManifest(); // This line was added
}
應該仔細考慮資源是否應刊登在清單中或隱藏。 如果將資源新增至清單,則應以安全且可靠的方式進行設定。
總結
在自訂資源教學課程中,您已瞭解如何建立使用現有容器化應用程式 (MailDev) 的自定義 .NET Aspire 資源。 然後,您便用它來改善本機開發體驗,讓您輕鬆地測試應用程式內可能使用的電子郵件功能。 這些學習可套用至建置可用於 .NET.NET Aspire應用程式的其他自定義資源。 此特定範例未包含任何自定義整合,但可以建置自定義整合,讓開發人員更容易使用資源。 在此案例中,您可以依賴 .NET 平台中現有的 SmtpClient
類別來傳送電子郵件。