Sdílet prostřednictvím


Vytváření vlastních Aspire integrací hostování

Aspire zlepšuje vývojové prostředí tím, že poskytuje opakovaně použitelné stavební bloky, které je možné použít k rychlému uspořádání závislostí aplikací a jejich zveřejnění vlastnímu kódu. Jedním z klíčových stavebních bloků aplikace založené na Aspireje prostředek . Podívejte se na následující kód:

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);

V předchozím kódu jsou zastoupeny čtyři prostředky:

  1. cache: Kontejner Redis.
  2. pgserver: Kontejner Postgres.
  3. inventorydb: Databáze hostovaná v pgserver.
  4. inventoryservice: Aplikace ASP.NET Core.

Většina Aspiresouvisejícího kódu, který průměrný vývojář píše, se zaměřuje na přidávání prostředků do modelu aplikace a vytváření odkazů mezi nimi.

Klíčové prvky vlastního Aspire zdroje

Vytvoření vlastního prostředku v Aspire vyžaduje následující:

  1. Vlastní typ zdroje, který implementuje IResource
  2. Metoda rozšíření pro IDistributedApplicationBuilder s názvem Add{CustomResource}, kde {CustomResource} je název vlastního prostředku.

Pokud vlastní prostředek vyžaduje volitelnou konfiguraci, mohou vývojáři chtít implementovat metody rozšíření končící příponou With*, aby byly tyto konfigurační možnosti zjistitelné s využitím vzoru tvůrce .

Praktický příklad: MailDev

Abychom pochopili, jak vyvíjet vlastní prostředky, tento článek ukazuje příklad vytvoření vlastního prostředku pro MailDev. MailDev je opensourcový nástroj, který poskytuje místní poštovní server navržený tak, aby vývojářům umožnil otestovat chování při odesílání e-mailů v aplikaci. Další informace najdete v MailDevGitHub úložišti.

V tomto příkladu vytvoříte nový projekt Aspire jako testovací prostředí pro MailDev prostředek, který vytvoříte. I když můžete vytvářet vlastní prostředky v existujících Aspire projektech, je vhodné zvážit, jestli se vlastní prostředek může používat napříč několika řešeními založenými na Aspirea měl by být vyvinut jako opakovaně použitelná integrace.

Nastavení počátečního projektu

Vytvořte nový Aspire projekt, který se používá k otestování nového prostředku, který vyvíjíme.

dotnet new aspire -o MailDevResource
cd MailDevResource
dir

Po vytvoření projektu by se měl zobrazit seznam obsahující následující položky:

  • MailDevResource.AppHost: AppHost použitý k otestování vlastního prostředku.
  • MailDevResource.ServiceDefaults: Služba má výchozí nastavení projektu pro využití v projektech spojených se službami.
  • MailDevResource.sln: Soubor řešení odkazující na oba projekty.

Spuštěním následujícího příkazu ověřte, že se projekt může úspěšně sestavit a spustit:

dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj

Výstup konzoly by měl vypadat nějak takto:

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.

Výběrem odkazu na řídicí panel v prohlížeči zobrazíte Aspire řídicí panel:

Snímek obrazovky s prázdným Aspire řídicím panelem pro testovací projekt

Stisknutím kláves Ctrl+C aplikaci vypnete (kartu prohlížeče můžete zavřít).

Vytvoření knihovny pro rozšíření zdrojů

Aspire prostředky jsou pouze třídy a metody obsažené v knihovně tříd, která odkazuje na knihovnu Aspire Hosting (Aspire.Hosting). Umístěním zdroje do samostatného projektu ho můžete snadněji sdílet mezi aplikacemi založenými na Aspire a potenciálně ho zabalit a sdílet na NuGetu.

  1. Vytvořte projekt knihovny tříd s názvem MailDev. Hosting.

    dotnet new classlib -o MailDev.Hosting
    
  2. Přidejte Aspire.Hosting do knihovny tříd jako odkaz na balíček.

    dotnet add ./MailDev.Hosting/MailDev.Hosting.csproj package Aspire.Hosting --version 9.0.0
    

    Důležitý

    Verze, kterou zde zadáte, by se měla shodovat s Aspire verzí sady SDK používanou ve vašem řešení.

  3. Přidejte odkaz na knihovnu tříd do projektu MailDevResource.AppHost.

    dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
    
  4. Přidejte do souboru řešení projekt knihovny tříd.

    dotnet sln ./MailDevResource.sln add ./MailDev.Hosting/MailDev.Hosting.csproj
    

Po provedení následujících kroků můžete projekt spustit:

dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj

Výsledkem je zobrazení upozornění na konzolu:

.\.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]

Důvodem je to, že Aspire zpracovává odkazy na projekt v AppHost, jako by se jedná o projekty služeb. Chcete-li určit Aspire, že odkaz na projekt by měl být považován za nefunkční projekt, upravte MailDevResource.AppHostMailDevResource.AppHost.csproj odkaz projektu na soubory MailDev.Hosting tak, aby zněl následovně:

<ItemGroup>
  <!-- The IsAspireProjectResource attribute tells 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>

Když teď spustíte AppHost, v konzole se nezobrazí žádné upozornění.

Definování typů prostředků

To je .MailDev Knihovna tříd hostování obsahuje typ prostředku a metody rozšíření pro přidání prostředku do AppHost. Měli byste se nejprve zamyslet nad prostředím, které chcete vývojářům poskytnout při používání vlastního prostředku. V případě tohoto vlastního prostředku byste chtěli, aby vývojáři mohli psát kód takto:

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.AddProject<Projects.NewsletterService>("newsletterservice")
       .WithReference(maildev);

K tomu potřebujete vlastní prostředek s názvem MailDevResource, který implementuje IResourceWithConnectionString, aby ho uživatelé mohli použít s rozšířením WithReference k vložení podrobností o připojení pro server MailDev jako připojovací řetězec.

MailDev je k dispozici jako zdroj kontejneru, takže budete chtít také použít odvození z ContainerResource, abychom mohli využít různá předpřipravená rozšíření zaměřená na kontejnery v Aspire.

Nahraďte obsah souboru Class1.cs v projektu MailDev.Hosting a přejmenujte ho na MailDevResource.cs následujícím kódem:

// 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 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.HostAndPort)}"
        );
}

V předchozím vlastním zdroji jsou EndpointReference a ReferenceExpression příklady několika typů, které implementují kolekci rozhraní, například IManifestExpressionProvider, IValueProvidera IValueWithReferences. Další informace o těchto typech a jejich rolích Aspirenaleznete v technických podrobnostech.

Definujte rozšíření prostředků

Aby vývojáři mohli snadno používat vlastní prostředek, je potřeba do projektu AddMailDev přidat metodu rozšíření s názvem MailDev.Hosting. Metoda rozšíření AddMailDev zodpovídá za konfiguraci prostředku tak, aby se úspěšně spustil jako kontejner.

Do nového souboru s názvem MailDevResourceBuilderExtensions.cs v projektu MailDev.Hosting přidejte následující kód:

using Aspire.Hosting.ApplicationModel;

// Put extensions in the Aspire.Hosting namespace to ease discovery as referencing
// the 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 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";
}

Ověření vlastní integrace v AppHostu

Teď, když je základní struktura vlastního prostředku hotová, je načase ji otestovat v reálném projektu AppHost. Otevřete soubor AppHost.cs v projektu MailDevResource.AppHost a aktualizujte ho následujícím kódem:

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.Build().Run();

Po aktualizaci AppHost.cs souboru spusťte projekt AppHost a otevřete řídicí panel:

dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj

Po chvíli řídicí panel ukazuje, že je spuštěný maildev prostředek a bude k dispozici hypertextový odkaz, který přejde do webové aplikace MailDev, která zobrazuje obsah každého e-mailu, který vaše aplikace odesílá.

Řídicí Aspire panel by měl vypadat nějak takto:

MailDev zdroj viditelný na Aspire řídicím panelu.

webová aplikace MailDev by měla vypadat nějak takto:

MailDev webové uživatelské rozhraní běžící jako kontejner spravované pomocí Aspire.

.NET Přidání projektu služby do appHostu pro testování

Jakmile Aspire úspěšně spustí integraci MailDev, je na čase využít informace o připojení pro MailDev v rámci projektu .NET. Běžně Aspire existuje hostitelský balíček a jeden nebo více balíčků komponent. Představte si například:

  • hostingový balíček: Používá se k reprezentaci prostředků v modelu aplikace.
    • Aspire.Hosting.Redis
  • balíčky komponent: Slouží ke konfiguraci a využívání klientských knihoven.
    • Aspire.StackExchange.Redis
    • Aspire.StackExchange.Redis.DistributedCaching
    • Aspire.StackExchange.Redis.OutputCaching

V případě MailDev prostředku už platforma .NET má klienta SMTP (Simple Mail Transfer Protocol) ve formě SmtpClient. V tomto příkladu použijete toto stávající rozhraní API kvůli jednoduchosti, i když jiné typy prostředků můžou těžit z vlastních integračních knihoven, které vývojářům pomůžou.

K otestování kompletního scénáře potřebujete projekt .NET, do kterého můžeme vložit informace o připojení pro prostředek MailDev. Přidání projektu webového rozhraní API:

  1. Vytvořte nový projekt .NET s názvem MailDevResource.NewsletterService.

    dotnet new webapi --use-minimal-apis -o MailDevResource.NewsletterService
    
  2. Přidejte odkaz na projekt MailDev.Hosting.

    dotnet add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
    
  3. Přidejte odkaz na projekt MailDevResource.AppHost.

    dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
    
  4. Přidejte nový projekt do souboru řešení.

    dotnet sln ./MailDevResource.sln add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
    

Po přidání projektu a aktualizaci odkazů otevřete AppHost.cs projektu MailDevResource.AppHost.csproj a aktualizujte zdrojový soubor tak, aby vypadal takto:

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.AddProject<Projects.MailDevResource_NewsletterService>("newsletterservice")
       .WithReference(maildev);

builder.Build().Run();

Po aktualizaci AppHost.cs souboru znovu spusťte AppHost. Potom ověřte, že služba bulletinu byla spuštěna a zda byla do procesu přidána proměnná prostředí ConnectionStrings__maildev. Na stránce Zdroje najděte newsletterservice řádek a ve sloupci Podrobnosti vyberte odkaz Zobrazit:

Proměnné prostředí pro službu bulletinu na Aspire řídicím panelu

Předchozí snímek obrazovky ukazuje proměnné prostředí pro newsletterservice projekt. Proměnná prostředí ConnectionStrings__maildev je připojovací řetězec, který do projektu byl vložen prostřednictvím prostředku maildev.

Odesílání zpráv pomocí připojovacího řetězce

Chcete-li použít podrobnosti o připojení SMTP, které byly vloženy do projektu služby newsletteru, vložíte instanci SmtpClient do kontejneru pro injekci závislostí jako singleton. Do souboru Program.cs v projektu MailDevResource.NewsletterService přidejte následující kód, který nastaví službu singleton. Do třídy Program bezprostředně za komentář // Add services to the container přidejte následující kód:

builder.Services.AddSingleton<SmtpClient>(sp =>
{
    var smtpUri = new Uri(builder.Configuration.GetConnectionString("maildev")!);

    var smtpClient = new SmtpClient(smtpUri.Host, smtpUri.Port);

    return smtpClient;
});

Spropitné

Tento fragment kódu ale spoléhá na oficiální SmtpClient; tento typ je zastaralý na některých platformách a nedoporučuje se u jiných. Modernější přístup pomocí Sady MailKit najdete v tématu Vytváření vlastních Aspire integrací klientů.

Chcete-li otestovat klienta, přidejte do služby bulletinu dvě jednoduché subscribe a unsubscribe metody POST. Pro přidání následujícího kódu, který v souboru MapGet projektu Program.cs nahradí volání "weatherforecast" a nastaví trasy ASP.NET Core, postupujte takto:

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);
});

Spropitné

Nezapomeňte odkazovat na obory názvů System.Net.Mail a Microsoft.AspNetCore.Mvc v Program.cs, pokud je editor kódu nepřidá automaticky.

Program.cs Po aktualizaci souboru spusťte AppHost a použijte prohlížeč nebo curl stiskněte následující adresy URL (případně pokud používáte Visual Studio.http soubory):

POST /subscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json

Pokud chcete toto rozhraní API použít, můžete k odeslání požadavku použít curl. Následující příkaz curl odešle požadavek HTTP POST na koncový bod subscribe a očekává hodnotu dotazovacího řetězce email pro přihlášení k odběru bulletinu. Hlavička Content-Type je nastavená na application/json označující, že text požadavku je ve formátu JSON.:

curl -H "Content-Type: application/json" --request POST https://localhost:7251/subscribe?email=test@test.com

Další API je koncový bod unsubscribe. Tento koncový bod slouží k odhlášení odběru bulletinu.

POST /unsubscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json

K odhlášení odběru bulletinu můžete použít následující příkaz curl a předat email parametr koncovému bodu unsubscribe jako řetězec dotazu:

curl -H "Content-Type: application/json" --request POST https://localhost:7251/unsubscribe?email=test@test.com

Spropitné

Ujistěte se, že nahradíte https://localhost:7251 správný localhost port (adresa URL hostitele apphost, který používáte).

Pokud tato volání rozhraní API vrátí úspěšnou odpověď (HTTP 200, OK), měli byste být schopni vybrat na prostředku maildev řídicí panel, a pak MailDev UI zobrazí e-maily, které byly odeslány na koncový bod SMTP.

e-maily viditelné v uživatelském rozhraní MailDev

Technické podrobnosti

V následujících částech jsou popsány různé technické podrobnosti, které jsou důležité pochopit při vývoji vlastních prostředků pro Aspire.

Zabezpečení sítí

V tomto příkladu je MailDev kontejnerový prostředek, který je zpřístupněn hostitelskému počítači přes protokol HTTP a SMTP. Prostředek MailDev je vývojový nástroj a není určený pro produkční použití. Pokud chcete místo toho použít PROTOKOL HTTPS, přečtěte si MailDev: KonfiguraceHTTPS .

Při vývoji vlastních prostředků, které zpřístupňují síťová zakončení, je důležité zvážit bezpečnostní důsledky těchto prostředků. Pokud je například prostředek databází, je důležité zajistit, aby byla databáze zabezpečená a že připojovací řetězec není vystavený veřejnému internetu.

Typy ReferenceExpression a EndpointReference

V předchozím kódu měl MailDevResource dvě vlastnosti:

Mezi tyto typy patří několik typů, které se používají v rámci Aspire k reprezentaci konfiguračních dat, která nejsou dokončena, dokud se projekt Aspire nespustí nebo nepublikuje do cloudu prostřednictvím nástroje, jako je Azure Developer CLI (azd).

Základním problémem, který tyto typy pomáhají vyřešit, je odložení řešení konkrétních informací o konfiguraci, dokud všechny informace jsou k dispozici.

Například MailDevResource zveřejňuje vlastnost s názvem ConnectionStringExpression podle požadavků rozhraní IResourceWithConnectionString. Typ vlastnosti je ReferenceExpression a je vytvořen předáním interpolovaného řetězce metodě Create.

public ReferenceExpression ConnectionStringExpression =>
    ReferenceExpression.Create(
        $"smtp://{SmtpEndpoint.Property(EndpointProperty.HostAndPort)}"
    );

Podpis metody Create je následující:

public static ReferenceExpression Create(
    in ExpressionInterpolatedStringHandler handler)

Toto není běžný argument String. Metoda používá interpolovaný vzor obslužné rutiny řetězcůpro zachycení interpolované řetězcové šablony a hodnot, na které se v ní odkazuje, aby bylo možné provádět vlastní zpracování. V případě Aspire jsou tyto podrobnosti zachyceny ve ReferenceExpression, který lze vyhodnotit, jakmile jsou dostupné všechny hodnoty uvedené v interpolovaném řetězci.

Tok provádění funguje takto:

  1. Prostředek, který implementuje IResourceWithConnectionString, se přidá do modelu (například AddMailDev(...)).
  2. IResourceBuilder<MailDevResource> je předán WithReference, který má zvláštní přetížení pro zpracování implementátorů IResourceWithConnectionString.
  3. Obklopí WithReference prostředek v ConnectionStringReference instanci a objekt se zachytí do EnvironmentCallbackAnnotation, který se vyhodnocuje po sestavení a spuštění Aspire projektu.
  4. Proces, který odkazuje na připojovací řetězec, začne Aspire vyhodnocovat výraz. Nejprve získá ConnectionStringReference a zavolá IValueProvider.GetValueAsync.
  5. Metoda GetValueAsync získá hodnotu vlastnosti ConnectionStringExpression, aby získala instanci ReferenceExpression.
  6. Metoda IValueProvider.GetValueAsync potom volá GetValueAsync ke zpracování dříve zachyceného interpolovaného řetězce.
  7. Vzhledem k tomu, že interpolovaný řetězec obsahuje odkazy na jiné typy odkazů, jako je například EndpointReference jsou také vyhodnoceny a nahrazeny reálnou hodnotou (která je nyní k dispozici).

Publikování manifestu

Rozhraní IManifestExpressionProvider je navržené tak, aby vyřešilo problém sdílení informací o připojení mezi prostředky při nasazení. Řešení tohoto konkrétního problému je popsáno v přehledu vnitrosmyčkového sítíAspire. Podobně jako místní vývoj je mnoho hodnot nezbytných ke konfiguraci aplikace, ale není možné je určit, dokud se aplikace nenasadí prostřednictvím nástroje, jako je azd (Azure Developer CLI).

Pro vyřešení tohoto problému Aspire vytvoří soubor manifestu , který azd a další nástroje nasazení interpretují. Místo zadávání konkrétních hodnot pro informace o připojení mezi prostředky se používá syntaxe výrazů, kterou nástroje pro nasazení vyhodnocují. Obecně se soubor manifestu vývojářům nezobrazuje, ale pro ruční kontrolu je možné ho vygenerovat. Následující příkaz lze použít na AppHost k vytvoření manifestu.

dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj -- --publisher manifest --output-path aspire-manifest.json

Tento příkaz vytvoří soubor manifestu jako následující:

{
  "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"
        }
      }
    }
  }
}

Protože MailDevResource implementuje IResourceWithConnectionString, logika publikování manifestu v Aspire ví, že i když je MailDevResource prostředek kontejneru, potřebuje i pole connectionString. Pole connectionString odkazuje na další části prostředku maildev v manifestu, aby vytvořilo konečný řetězec:

{
    // ... other content omitted.
    "connectionString": "smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port}"
}

Aspire ví, jak tento řetězec vytvořit, protože sleduje ConnectionStringExpression a vytváří konečný řetězec prostřednictvím IManifestExpressionProvider rozhraní (podobným způsobem, jak se používá IValueProvider rozhraní).

MailDevResource se automaticky zahrne do manifestu, protože je odvozen z ContainerResource. Autoři prostředků se mohou rozhodnout zabránit výstupu obsahu do manifestu pomocí metody rozšíření ExcludeFromManifest v sestavovači prostředků.

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
}

Pečlivě je potřeba vzít v úvahu, jestli se prostředek má v manifestu vyskytovat, nebo jestli má být potlačen. Pokud se prostředek přidává do manifestu, měl by být nakonfigurovaný tak, aby byl bezpečný a bezpečný pro použití.

Shrnutí

V kurzu vlastního prostředku jste se naučili, jak vytvořit vlastní prostředek Aspire, který používá existující kontejnerovou aplikaci (MailDev). Pak jste ho použili ke zlepšení místního vývojového prostředí tím, že zjednodušíte testování možností e-mailu, které se můžou použít v aplikaci. Tyto poznatky se dají použít k vytváření dalších vlastních prostředků, které je možné použít v Aspireaplikacích založených na nich. Tento konkrétní příklad neobsahuje žádné vlastní integrace, ale je možné vytvořit vlastní integrace, aby vývojáři mohli prostředek snadněji používat. V tomto scénáři jste se mohli spolehnout na existující třídu SmtpClient na platformě .NET k odesílání e-mailů.

Další kroky